diff options
author | Christian Blättler <blatc2@bfh.ch> | 2023-11-07 15:11:28 +0100 |
---|---|---|
committer | Christian Blättler <blatc2@bfh.ch> | 2023-11-07 15:11:28 +0100 |
commit | 247e96cff1204cebd87e965cbf698e3506efdc52 (patch) | |
tree | a3f5f829e1777d05072547a8b6e125e48a944a77 /src | |
parent | 92c3189b150ff79c8ce0f5a296e2cdddbe132519 (diff) | |
parent | 2992b42baedc5c2f5afeaef89c55604c45849370 (diff) |
Merge branch 'master' into feature/tokens
Diffstat (limited to 'src')
116 files changed, 9647 insertions, 2462 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index bc1598b07..41c4f5205 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1940,7 +1940,7 @@ check_recoup (struct CoinContext *cc, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { struct DenominationSummary *ds; enum GNUNET_DB_QueryStatus qs; @@ -2071,7 +2071,7 @@ recoup_cb (void *cls, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { struct CoinContext *cc = cls; @@ -2139,7 +2139,7 @@ recoup_refresh_cb (void *cls, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { struct CoinContext *cc = cls; const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue; diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c index fc7395994..8ec2b223e 100644 --- a/src/auditor/taler-helper-auditor-deposits.c +++ b/src/auditor/taler-helper-auditor-deposits.c @@ -30,6 +30,27 @@ #include "taler_signatures.h" #include "report-lib.h" +/* +-- +-- SELECT serial_id,h_contract_terms,h_wire,merchant_pub ... +-- FROM auditor.depoist_confirmations +-- WHERE NOT ancient +-- ORDER BY exchange_timestamp ASC; +-- SELECT 1 +- FROM exchange.deposits dep + WHERE ($RESULT.contract_terms = dep.h_contract_terms) AND ($RESULT.h_wire = dep.h_wire) AND ...); +-- IF FOUND +-- DELETE FROM auditor.depoist_confirmations +-- WHERE serial_id = $RESULT.serial_id; +-- SELECT exchange_timestamp AS latest +-- FROM exchange.deposits ORDER BY exchange_timestamp DESC; +-- latest -= 1 hour; // time is not exactly monotonic... +-- UPDATE auditor.deposit_confirmations +-- SET ancient=TRUE +-- WHERE exchange_timestamp < latest +-- AND NOT ancient; +*/ + /** * Return value from main(). diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c index eca3c42aa..f589ebfda 100644 --- a/src/auditor/taler-helper-auditor-reserves.c +++ b/src/auditor/taler-helper-auditor-reserves.c @@ -678,7 +678,7 @@ handle_recoup_by_reserve ( const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { struct ReserveContext *rc = cls; struct ReserveSummary *rs; diff --git a/src/auditordb/0002-auditor_balances.sql b/src/auditordb/0002-auditor_balances.sql index 396381e0b..5a25a0e2a 100644 --- a/src/auditordb/0002-auditor_balances.sql +++ b/src/auditordb/0002-auditor_balances.sql @@ -14,13 +14,19 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -CREATE TABLE IF NOT EXISTS auditor_balances ( - balance_key TEXT PRIMARY KEY - ,balance_value taler_amount - ); -COMMENT ON TABLE auditor_balances +SET search_path TO auditor; +CREATE TABLE IF NOT EXISTS auditor_balances +( + balance_key TEXT + ,balance_value taler_amount + ,PRIMARY KEY (balance_key) +); +COMMENT +ON TABLE auditor_balances IS 'table storing various global balances of the auditor'; -COMMENT ON COLUMN auditor_balances.balance_key +COMMENT +ON COLUMN auditor_balances.balance_key IS 'unique name for the balance value'; -COMMENT ON COLUMN auditor_balances.balance_value +COMMENT +ON COLUMN auditor_balances.balance_value IS 'balance amount'; diff --git a/src/auditordb/0002-auditor_denomination_pending.sql b/src/auditordb/0002-auditor_denomination_pending.sql index ea47dc0da..0dee6ecab 100644 --- a/src/auditordb/0002-auditor_denomination_pending.sql +++ b/src/auditordb/0002-auditor_denomination_pending.sql @@ -14,6 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_denomination_pending (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,denom_balance taler_amount NOT NULL diff --git a/src/auditordb/0002-auditor_deposit_confirmations.sql b/src/auditordb/0002-auditor_deposit_confirmations.sql new file mode 100644 index 000000000..a0725925c --- /dev/null +++ b/src/auditordb/0002-auditor_deposit_confirmations.sql @@ -0,0 +1,44 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2014--2022 Taler Systems SA +-- +-- TALER 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, or (at your option) any later version. +-- +-- TALER 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 +-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +-- + +SET search_path TO auditor; +DROP TABLE IF EXISTS deposit_confirmations; +CREATE TABLE IF NOT EXISTS auditor_deposit_confirmations +(deposit_confirmation_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE + ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) + ,h_policy BYTEA NOT NULL CHECK (LENGTH(h_policy)=64) + ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64) + ,exchange_timestamp INT8 NOT NULL + ,refund_deadline INT8 NOT NULL + ,wire_deadline INT8 NOT NULL + ,total_without_fee taler_amount NOT NULL + ,coin_pubs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_pubs)>0) + ,coin_sigs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_sigs)=CARDINALITY(coin_pubs)) + ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) + ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64) + ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32) + ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) + ,suppressed BOOLEAN NOT NULL DEFAULT FALSE + ,ancient BOOLEAN NOT NULL DEFAULT FALSE + ,PRIMARY KEY (h_contract_terms,h_wire,merchant_pub,exchange_sig,exchange_pub,master_sig) + ); +COMMENT ON TABLE auditor_deposit_confirmations + IS 'deposit confirmation sent to us by merchants; we must check that the exchange reported these properly.'; + +CREATE INDEX IF NOT EXISTS auditor_deposit_confirmations_not_ancient + ON auditor_deposit_confirmations + (exchange_timestamp ASC) + WHERE NOT ancient;
\ No newline at end of file diff --git a/src/auditordb/0002-auditor_exchange_signkeys.sql b/src/auditordb/0002-auditor_exchange_signkeys.sql index cf5b01c8a..127365e64 100644 --- a/src/auditordb/0002-auditor_exchange_signkeys.sql +++ b/src/auditordb/0002-auditor_exchange_signkeys.sql @@ -14,6 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +DROP TABLE IF EXISTS auditor_exchange_signkeys; CREATE TABLE IF NOT EXISTS auditor_exchange_signkeys (exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) diff --git a/src/auditordb/0002-auditor_historic_denomination_revenue.sql b/src/auditordb/0002-auditor_historic_denomination_revenue.sql index 98146aae7..19c0b5829 100644 --- a/src/auditordb/0002-auditor_historic_denomination_revenue.sql +++ b/src/auditordb/0002-auditor_historic_denomination_revenue.sql @@ -14,6 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_historic_denomination_revenue (denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64) ,revenue_timestamp INT8 NOT NULL diff --git a/src/auditordb/0002-auditor_historic_reserve_summary.sql b/src/auditordb/0002-auditor_historic_reserve_summary.sql index e71ae8b7a..819c4e160 100644 --- a/src/auditordb/0002-auditor_historic_reserve_summary.sql +++ b/src/auditordb/0002-auditor_historic_reserve_summary.sql @@ -14,6 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_historic_reserve_summary (start_date INT8 PRIMARY KEY ,end_date INT8 NOT NULL diff --git a/src/auditordb/0002-auditor_purses.sql b/src/auditordb/0002-auditor_purses.sql index 9ba5955eb..7cebd8894 100644 --- a/src/auditordb/0002-auditor_purses.sql +++ b/src/auditordb/0002-auditor_purses.sql @@ -14,12 +14,13 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_purses (auditor_purses_rowid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32) - ,balance taler_amount NOT NULL DEFAULT(0) + ,balance taler_amount NOT NULL DEFAULT(0,0) ,target taler_amount NOT NULL ,expiration_date INT8 NOT NULL ); -COMMENT ON TABLE purses +COMMENT ON TABLE auditor_purses IS 'all of the purses and their respective balances that the auditor is aware of'; diff --git a/src/auditordb/0002-auditor_reserves.sql b/src/auditordb/0002-auditor_reserves.sql index 834d245ef..1ed56be61 100644 --- a/src/auditordb/0002-auditor_reserves.sql +++ b/src/auditordb/0002-auditor_reserves.sql @@ -14,6 +14,7 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- +SET search_path TO auditor; CREATE TABLE IF NOT EXISTS auditor_reserves (auditor_reserves_rowid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE ,reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32) diff --git a/src/auditordb/0002-deposit_confirmations.sql b/src/auditordb/0002-deposit_confirmations.sql deleted file mode 100644 index 1d63bdb6e..000000000 --- a/src/auditordb/0002-deposit_confirmations.sql +++ /dev/null @@ -1,35 +0,0 @@ --- --- This file is part of TALER --- Copyright (C) 2014--2022 Taler Systems SA --- --- TALER 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, or (at your option) any later version. --- --- TALER 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 --- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> --- - -CREATE TABLE IF NOT EXISTS deposit_confirmations - (deposit_confirmation_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) - ,h_policy BYTEA NOT NULL CHECK (LENGTH(h_policy)=64) - ,h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64) - ,exchange_timestamp INT8 NOT NULL - ,refund_deadline INT8 NOT NULL - ,wire_deadline INT8 NOT NULL - ,total_without_fee taler_amount NOT NULL - ,coin_pubs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_pubs)>0) - ,coin_sigs BYTEA[] NOT NULL CHECK (CARDINALITY(coin_sigs)=CARDINALITY(coin_pubs)) - ,merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32) - ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64) - ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32) - ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) - ,PRIMARY KEY (h_contract_terms,h_wire,coin_pub,merchant_pub,exchange_sig,exchange_pub,master_sig) - ); -COMMENT ON TABLE deposit_confirmations - IS 'deposit confirmation sent to us by merchants; we must check that the exchange reported these properly.'; diff --git a/src/auditordb/auditor-0001.sql b/src/auditordb/auditor-0001.sql index b755da4b0..779f61aaa 100644 --- a/src/auditordb/auditor-0001.sql +++ b/src/auditordb/auditor-0001.sql @@ -296,11 +296,18 @@ CREATE TABLE IF NOT EXISTS deposit_confirmations ,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64) ,exchange_pub BYTEA NOT NULL CHECK (LENGTH(exchange_pub)=32) ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64) + ,suppressed BOOLEAN NOT NULL DEFAULT FALSE + ,ancient BOOLEAN NOT NULL DEFAULT FALSE ,PRIMARY KEY (h_contract_terms,h_wire,merchant_pub,exchange_sig,exchange_pub,master_sig) ); COMMENT ON TABLE deposit_confirmations IS 'deposit confirmation sent to us by merchants; we must check that the exchange reported these properly.'; +CREATE INDEX IF NOT EXISTS auditor_deposit_confirmations_not_ancient + ON deposit_confirmations + (exchange_timestamp ASC) + WHERE NOT ancient; + CREATE TABLE IF NOT EXISTS auditor_predicted_result (master_pub BYTEA NOT NULL CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE diff --git a/src/auditordb/auditor-0002.sql.in b/src/auditordb/auditor-0002.sql.in index ab0db2fb8..5b8f9e074 100644 --- a/src/auditordb/auditor-0002.sql.in +++ b/src/auditordb/auditor-0002.sql.in @@ -24,13 +24,18 @@ COMMENT ON SCHEMA auditor IS 'taler-auditor data'; SELECT _v.register_patch('auditor-0002', NULL, NULL); SET search_path TO auditor; -CREATE TYPE taler_amount - AS - (val INT8 - ,frac INT4 - ); -COMMENT ON TYPE taler_amount - IS 'Stores an amount, fraction is in units of 1/100000000 of the base value'; +DO $$ BEGIN + CREATE TYPE taler_amount + AS + (val INT8 + ,frac INT4 + ); + COMMENT ON TYPE taler_amount + IS 'Stores an amount, fraction is in units of 1/100000000 of the base value'; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; + #include "0002-auditor_balances.sql" #include "0002-auditor_denomination_pending.sql" @@ -40,6 +45,6 @@ COMMENT ON TYPE taler_amount #include "0002-auditor_progress.sql" #include "0002-auditor_purses.sql" #include "0002-auditor_reserves.sql" -#include "0002-deposit_confirmations.sql" +#include "0002-auditor_deposit_confirmations.sql" COMMIT; diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index d39d08b91..f8fbe66cf 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -248,7 +248,7 @@ run (void *cls) GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&denom_priv, &denom_pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, 1024)); TALER_denom_pub_hash (&denom_pub, &denom_pub_hash); diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c index 9b2b1d4fd..228d050e4 100644 --- a/src/benchmark/taler-aggregator-benchmark.c +++ b/src/benchmark/taler-aggregator-benchmark.c @@ -489,18 +489,18 @@ run (void *cls, struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature bds; struct TALER_PlanchetMasterSecretP ps; - struct TALER_ExchangeWithdrawValues alg_values; struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_AgeCommitmentHash hac; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; + const struct TALER_ExchangeWithdrawValues *alg_values; RANDOMIZE (&coin_pub); GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&pk, &denom_pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, 1024)); - alg_values.cipher = TALER_DENOMINATION_RSA; + alg_values = TALER_denom_ewv_rsa_singleton (); denom_pub.age_mask = issue.age_mask; TALER_denom_pub_hash (&denom_pub, &h_denom_pub); @@ -522,7 +522,7 @@ run (void *cls, } TALER_planchet_blinding_secret_create (&ps, - &alg_values, + TALER_denom_ewv_rsa_singleton (), &bks); { @@ -546,9 +546,10 @@ run (void *cls, GNUNET_assert (GNUNET_OK == TALER_denom_blind (&denom_pub, &bks, + NULL, &hac, &coin_pub, - &alg_values, + alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == @@ -562,7 +563,7 @@ run (void *cls, &bds, &bks, &c_hash, - &alg_values, + alg_values, &denom_pub)); TALER_blinded_denom_sig_free (&bds); TALER_denom_pub_free (&denom_pub); diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index fed29437e..3eb0ba460 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -4305,13 +4305,13 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa, stamp_expire_withdraw.abs_time); TALER_denom_pub_hash (&denom_pub, &h_denom_pub); - switch (denom_pub.cipher) + switch (denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: { struct TALER_RsaPubHashP h_rsa; - TALER_rsa_pub_hash (denom_pub.details.rsa_public_key, + TALER_rsa_pub_hash (denom_pub.bsign_pub_key->details.rsa_public_key, &h_rsa); ok = TALER_exchange_secmod_rsa_verify (&h_rsa, section_name, @@ -4321,11 +4321,11 @@ show_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa, &secm_sig); } break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct TALER_CsPubHashP h_cs; - TALER_cs_pub_hash (&denom_pub.details.cs_public_key, + TALER_cs_pub_hash (&denom_pub.bsign_pub_key->details.cs_public_key, &h_cs); ok = TALER_exchange_secmod_cs_verify (&h_cs, section_name, @@ -4785,13 +4785,14 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa, TALER_denom_pub_hash (&denom_pub, &h_denom_pub); - switch (denom_pub.cipher) + + switch (denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: { struct TALER_RsaPubHashP h_rsa; - TALER_rsa_pub_hash (denom_pub.details.rsa_public_key, + TALER_rsa_pub_hash (denom_pub.bsign_pub_key->details.rsa_public_key, &h_rsa); if (GNUNET_OK != TALER_exchange_secmod_rsa_verify (&h_rsa, @@ -4811,11 +4812,11 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub_rsa, } } break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct TALER_CsPubHashP h_cs; - TALER_cs_pub_hash (&denom_pub.details.cs_public_key, + TALER_cs_pub_hash (&denom_pub.bsign_pub_key->details.cs_public_key, &h_cs); if (GNUNET_OK != TALER_exchange_secmod_cs_verify (&h_cs, diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c b/src/exchange/taler-exchange-httpd_age-withdraw.c index 4a7d6b1a8..bcbb71563 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw.c @@ -231,11 +231,17 @@ parse_age_withdraw_json ( json_array_foreach (j_kappa_coin_evs, kappa, value) { struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_blinded_planchet (NULL, &awc->coin_evs[off + kappa]), + /* FIXME-Oec: This allocation is never freed! */ + TALER_JSON_spec_blinded_planchet (NULL, + &awc->coin_evs[off + kappa]), GNUNET_JSON_spec_end () }; + if (GNUNET_OK != - GNUNET_JSON_parse (value, spec, NULL, NULL)) + GNUNET_JSON_parse (value, + spec, + NULL, + NULL)) { GNUNET_snprintf (buf, sizeof(buf), @@ -249,12 +255,11 @@ parse_age_withdraw_json ( /* Continue to hash of the coin candidates */ { struct TALER_BlindedCoinHashP bch; + ret = TALER_coin_ev_hash (&awc->coin_evs[off + kappa], &awc->denom_hs[idx], &bch); - GNUNET_assert (GNUNET_OK == ret); - GNUNET_CRYPTO_hash_context_read (hash_context, &bch, sizeof(bch)); @@ -448,7 +453,8 @@ are_denominations_valid ( return GNUNET_SYSERR; /* Ensure the ciphers from the planchets match the denominations' */ - if (dk->denom_pub.cipher != coin_evs[i].cipher) + if (dk->denom_pub.bsign_pub_key->cipher != + coin_evs[i].blinded_message->cipher) { GNUNET_break_op (0); *result = TALER_MHD_reply_with_ec (connection, @@ -829,7 +835,7 @@ age_withdraw_transaction (void *cls, * @param connection HTTP-connection to the client * @param awc The context for the current age withdraw request * @param[out] result On error, a HTTP-response will be queued and result set accordingly - * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise */ static enum GNUNET_GenericReturnValue sign_and_do_age_withdraw ( @@ -863,8 +869,8 @@ sign_and_do_age_withdraw ( csds[i].h_denom_pub = &awc->denom_hs[i]; } - ec = TEH_keys_denomination_batch_sign (csds, - awc->num_coins, + ec = TEH_keys_denomination_batch_sign (awc->num_coins, + csds, false, denom_sigs); if (TALER_EC_NONE != ec) diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c index b77b5e377..9b9f1cb88 100644 --- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c +++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c @@ -194,8 +194,8 @@ EXIT: * @param reserve_pub Reserve public key used in the original age-withdraw request * @param[out] commitment Data from the original age-withdraw request * @param[out] result In the error cases, a response will be queued with MHD and this will be the result. - * @return GNUNET_OK if the withdraw request has been found, - * GNUNET_SYSERROR if we did not find the request in the DB + * @return #GNUNET_OK if the withdraw request has been found, + * #GNUNET_SYSERR if we did not find the request in the DB */ static enum GNUNET_GenericReturnValue find_original_commitment ( @@ -217,20 +217,17 @@ find_original_commitment ( { case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: return GNUNET_OK; /* Only happy case */ - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: *result = TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_FOUND, TALER_EC_EXCHANGE_AGE_WITHDRAW_COMMITMENT_UNKNOWN, NULL); return GNUNET_SYSERR; - case GNUNET_DB_STATUS_HARD_ERROR: *result = TALER_MHD_reply_with_ec (connection, TALER_EC_GENERIC_DB_FETCH_FAILED, "get_age_withdraw_info"); return GNUNET_SYSERR; - case GNUNET_DB_STATUS_SOFT_ERROR: break; /* try again */ default: @@ -300,6 +297,7 @@ calculate_blinded_hash ( &acp); TALER_age_commitment_hash (&acp.commitment, &ach); + TALER_age_commitment_proof_free (&acp); } /* Next: calculate planchet */ @@ -307,50 +305,47 @@ calculate_blinded_hash ( struct TALER_CoinPubHashP c_hash; struct TALER_PlanchetDetail detail = {0}; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = denom_key->denom_pub.bsign_pub_key->cipher + }; struct TALER_ExchangeWithdrawValues alg_values = { - .cipher = denom_key->denom_pub.cipher, + .blinding_inputs = &bi }; + union GNUNET_CRYPTO_BlindSessionNonce nonce; + union GNUNET_CRYPTO_BlindSessionNonce *noncep = NULL; - if (TALER_DENOMINATION_CS == alg_values.cipher) + // FIXME: add logic to denom.c to do this! + if (GNUNET_CRYPTO_BSA_CS == bi.cipher) { - struct TALER_CsNonce nonce; + struct TEH_CsDeriveData cdd = { + .h_denom_pub = &denom_key->h_denom_pub, + .nonce = &nonce.cs_nonce, + }; TALER_cs_withdraw_nonce_derive (secret, - &nonce); - - { - struct TEH_CsDeriveData cdd = { - .h_denom_pub = &denom_key->h_denom_pub, - .nonce = &nonce, - }; - - GNUNET_assert (TALER_EC_NONE == - TEH_keys_denomination_cs_r_pub ( - &cdd, - false, - &alg_values.details.cs_values)); - } - - detail.blinded_planchet.details.cs_blinded_planchet.nonce = nonce; + &nonce.cs_nonce); + noncep = &nonce; + GNUNET_assert (TALER_EC_NONE == + TEH_keys_denomination_cs_r_pub ( + &cdd, + false, + &bi.details.cs_values)); } - TALER_planchet_blinding_secret_create (secret, &alg_values, &bks); - TALER_planchet_setup_coin_priv (secret, &alg_values, &coin_priv); - ret = TALER_planchet_prepare (&denom_key->denom_pub, &alg_values, &bks, + noncep, &coin_priv, &ach, &c_hash, &detail); - if (GNUNET_OK != ret) { GNUNET_break (0); @@ -365,7 +360,7 @@ calculate_blinded_hash ( ret = TALER_coin_ev_hash (&detail.blinded_planchet, &denom_key->h_denom_pub, bch); - + TALER_blinded_planchet_free (&detail.blinded_planchet); GNUNET_assert (GNUNET_OK == ret); } @@ -602,6 +597,11 @@ TEH_handler_age_withdraw_reveal ( } while(0); GNUNET_JSON_parse_free (spec); + for (unsigned int i = 0; i<actx.num_coins; i++) + TALER_blinded_denom_sig_free (&actx.commitment.denom_sigs[i]); + GNUNET_free (actx.commitment.denom_sigs); + GNUNET_free (actx.commitment.denom_pub_hashes); + GNUNET_free (actx.commitment.denom_serials); GNUNET_free (actx.disclosed_coin_secrets); return result; } diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 87ca36e0a..32c39adce 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -376,7 +376,8 @@ parse_coin (struct MHD_Connection *connection, ? GNUNET_NO : GNUNET_SYSERR; } - if (dk->denom_pub.cipher != cdi->coin.denom_sig.cipher) + if (dk->denom_pub.bsign_pub_key->cipher != + cdi->coin.denom_sig.unblinded_sig->cipher) { /* denomination cipher and denomination signature cipher not the same */ GNUNET_JSON_parse_free (spec); @@ -391,12 +392,12 @@ parse_coin (struct MHD_Connection *connection, *deposit_fee = dk->meta.fees.deposit; /* check coin signature */ - switch (dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++; break; default: diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c b/src/exchange/taler-exchange-httpd_batch-withdraw.c index fe2108763..19a9cacf1 100644 --- a/src/exchange/taler-exchange-httpd_batch-withdraw.c +++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c @@ -534,14 +534,22 @@ batch_withdraw_transaction (void *cls, { struct PlanchetContext *pc = &wc->planchets[i]; const struct TALER_BlindedPlanchet *bp = &pc->blinded_planchet; - const struct TALER_CsNonce *nonce; + const union GNUNET_CRYPTO_BlindSessionNonce *nonce = NULL; bool denom_unknown = true; bool conflict = true; bool nonce_reuse = true; - nonce = (TALER_DENOMINATION_CS == bp->cipher) - ? &bp->details.cs_blinded_planchet.nonce - : NULL; + switch (bp->blinded_message->cipher) + { + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + break; + case GNUNET_CRYPTO_BSA_CS: + nonce = (const union GNUNET_CRYPTO_BlindSessionNonce *) + &bp->blinded_message->details.cs_blinded_message.nonce; + break; + } qs = TEH_plugin->do_batch_withdraw_insert (TEH_plugin->cls, nonce, &pc->collectable, @@ -626,8 +634,8 @@ prepare_transaction (const struct TEH_RequestContext *rc, enum TALER_ErrorCode ec; ec = TEH_keys_denomination_batch_sign ( - csds, wc->planchets_length, + csds, false, bss); if (TALER_EC_NONE != ec) @@ -797,7 +805,8 @@ parse_planchets (const struct TEH_RequestContext *rc, } return mret; } - if (dk->denom_pub.cipher != pc->blinded_planchet.cipher) + if (dk->denom_pub.bsign_pub_key->cipher != + pc->blinded_planchet.blinded_message->cipher) { /* denomination cipher and blinded planchet cipher not the same */ GNUNET_break_op (0); diff --git a/src/exchange/taler-exchange-httpd_common_deposit.c b/src/exchange/taler-exchange-httpd_common_deposit.c index 0c91f0bc9..898e23dd9 100644 --- a/src/exchange/taler-exchange-httpd_common_deposit.c +++ b/src/exchange/taler-exchange-httpd_common_deposit.c @@ -135,7 +135,8 @@ TEH_common_purse_deposit_parse_coin ( "PURSE CREATE")) ? GNUNET_NO : GNUNET_SYSERR; } - if (dk->denom_pub.cipher != coin->cpi.denom_sig.cipher) + if (dk->denom_pub.bsign_pub_key->cipher != + coin->cpi.denom_sig.unblinded_sig->cipher) { /* denomination cipher and denomination signature cipher not the same */ GNUNET_JSON_parse_free (spec); @@ -164,12 +165,12 @@ TEH_common_purse_deposit_parse_coin ( &coin->deposit_fee)); /* check coin signature */ - switch (dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++; break; default: diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c index 64892d363..e4fa4f5e4 100644 --- a/src/exchange/taler-exchange-httpd_csr.c +++ b/src/exchange/taler-exchange-httpd_csr.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as @@ -21,6 +21,7 @@ * @brief Handle /csr requests * @author Lucien Heuzeveldt * @author Gian Demarmles + * @author Christian Grothoff */ #include "platform.h" #include <gnunet/gnunet_util_lib.h> @@ -74,12 +75,12 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc, } { - struct TALER_ExchangeWithdrawValues ewvs[csr_requests_num]; + struct GNUNET_CRYPTO_BlindingInputValues ewvs[csr_requests_num]; { - struct TALER_CsNonce nonces[csr_requests_num]; + struct GNUNET_CRYPTO_CsSessionNonce nonces[csr_requests_num]; struct TALER_DenominationHashP denom_pub_hashes[csr_requests_num]; struct TEH_CsDeriveData cdds[csr_requests_num]; - struct TALER_DenominationCSPublicRPairP r_pubs[csr_requests_num]; + struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[csr_requests_num]; for (unsigned int i = 0; i < csr_requests_num; i++) { @@ -110,11 +111,11 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc, for (unsigned int i = 0; i < csr_requests_num; i++) { - const struct TALER_CsNonce *nonce = &nonces[i]; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce = &nonces[i]; const struct TALER_DenominationHashP *denom_pub_hash = &denom_pub_hashes[i]; - ewvs[i].cipher = TALER_DENOMINATION_CS; + ewvs[i].cipher = GNUNET_CRYPTO_BSA_CS; /* check denomination referenced by denom_pub_hash */ { struct TEH_KeyStateHandle *ksh; @@ -165,7 +166,8 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, "csr-melt"); } - if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_CS != + dk->denom_pub.bsign_pub_key->cipher) { /* denomination is valid but not for CS */ return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( @@ -176,8 +178,8 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc, cdds[i].h_denom_pub = denom_pub_hash; cdds[i].nonce = nonce; } /* for (i) */ - ec = TEH_keys_denomination_cs_batch_r_pub (cdds, - csr_requests_num, + ec = TEH_keys_denomination_cs_batch_r_pub (csr_requests_num, + cdds, true, r_pubs); if (TALER_EC_NONE != ec) @@ -200,10 +202,13 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc, for (unsigned int i = 0; i < csr_requests_num; i++) { json_t *csr_obj; + struct TALER_ExchangeWithdrawValues exw = { + .blinding_inputs = &ewvs[i] + }; csr_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_exchange_withdraw_values ("ewv", - &ewvs[i])); + &exw)); GNUNET_assert (NULL != csr_obj); GNUNET_assert (0 == json_array_append_new (csr_response_ewvs, @@ -226,10 +231,10 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, const json_t *root, const char *const args[]) { - struct TALER_CsNonce nonce; + struct GNUNET_CRYPTO_CsSessionNonce nonce; struct TALER_DenominationHashP denom_pub_hash; - struct TALER_ExchangeWithdrawValues ewv = { - .cipher = TALER_DENOMINATION_CS + struct GNUNET_CRYPTO_BlindingInputValues ewv = { + .cipher = GNUNET_CRYPTO_BSA_CS }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("nonce", @@ -300,7 +305,8 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, "csr-withdraw"); } - if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_CS != + dk->denom_pub.bsign_pub_key->cipher) { /* denomination is valid but not for CS */ return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( @@ -328,12 +334,17 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, NULL); } } + { + struct TALER_ExchangeWithdrawValues exw = { + .blinding_inputs = &ewv + }; - return TALER_MHD_REPLY_JSON_PACK ( - rc->connection, - MHD_HTTP_OK, - TALER_JSON_pack_exchange_withdraw_values ("ewv", - &ewv)); + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_OK, + TALER_JSON_pack_exchange_withdraw_values ("ewv", + &exw)); + } } diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index 68cc2da55..1ee573b0f 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021 Taler Systems SA + Copyright (C) 2021, 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -208,16 +208,20 @@ TEH_extensions_init () { const struct TALER_Extension *ext = it->extension; uint32_t typ = htonl (ext->type); - char *manifest = json_dumps (ext->manifest (ext), JSON_COMPACT); + json_t *jmani; + char *manifest; + jmani = ext->manifest (ext); + manifest = json_dumps (jmani, + JSON_COMPACT); + json_decref (jmani); TEH_plugin->set_extension_manifest (TEH_plugin->cls, ext->name, manifest); - + free (manifest); extension_update_event_cb (NULL, &typ, sizeof(typ)); - free (manifest); } return GNUNET_OK; diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 27b9d6c7f..913cd7343 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -432,10 +432,6 @@ struct WireFeeSet */ struct WireStateHandle { - /** - * Cached reply for /wire response. - */ - struct MHD_Response *wire_reply; /** * JSON reply for /wire response. @@ -474,9 +470,9 @@ struct WireStateHandle uint64_t wire_generation; /** - * HTTP status to return with this response. + * Is the wire data ready? */ - unsigned int http_status; + bool ready; }; @@ -594,7 +590,6 @@ destroy_wire_state (struct WireStateHandle *wsh) GNUNET_free (wfs->method); GNUNET_free (wfs); } - MHD_destroy_response (wsh->wire_reply); json_decref (wsh->json_reply); GNUNET_free (wsh->etag); GNUNET_free (wsh); @@ -742,13 +737,6 @@ struct AddContext json_t *a; /** - * Context we hash "everything" we add into. This is used - * to compute the etag. Technically, we only hash the - * master_sigs, as they imply the rest. - */ - struct GNUNET_HashContext *hc; - - /** * Set to the maximum end-date seen. */ struct GNUNET_TIME_Absolute max_seen; @@ -788,9 +776,6 @@ add_wire_fee (void *cls, "Database has wire fee with invalid signature. Skipping entry. Did the exchange offline public key change?\n"); return; } - GNUNET_CRYPTO_hash_context_read (ac->hc, - master_sig, - sizeof (*master_sig)); ac->max_seen = GNUNET_TIME_absolute_max (ac->max_seen, end_date.abs_time); wfs = GNUNET_new (struct WireFeeSet); @@ -835,7 +820,6 @@ build_wire_state (void) uint64_t wg = wire_generation; /* must be obtained FIRST */ enum GNUNET_DB_QueryStatus qs; struct WireStateHandle *wsh; - struct GNUNET_HashContext *hc; json_t *wads; wsh = GNUNET_new (struct WireStateHandle); @@ -849,10 +833,7 @@ build_wire_state (void) { GNUNET_break (0); json_decref (wire_accounts_array); - wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; - wsh->wire_reply - = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED, - "get_wire_accounts"); + wsh->ready = false; return wsh; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -861,12 +842,14 @@ build_wire_state (void) wire_fee_object = json_object (); GNUNET_assert (NULL != wire_fee_object); wsh->cache_expiration = GNUNET_TIME_UNIT_FOREVER_ABS; - hc = GNUNET_CRYPTO_hash_context_start (); { json_t *account; size_t index; - json_array_foreach (wire_accounts_array, index, account) { + json_array_foreach (wire_accounts_array, + index, + account) + { char *wire_method; const char *payto_uri = json_string_value (json_object_get (account, "payto_uri")); @@ -878,14 +861,9 @@ build_wire_state (void) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No wire method in `%s'\n", payto_uri); - wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; - wsh->wire_reply - = TALER_MHD_make_error ( - TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED, - payto_uri); + wsh->ready = false; json_decref (wire_accounts_array); json_decref (wire_fee_object); - GNUNET_CRYPTO_hash_context_abort (hc); return wsh; } if (NULL == json_object_get (wire_fee_object, @@ -894,8 +872,7 @@ build_wire_state (void) struct AddContext ac = { .wire_method = wire_method, .wsh = wsh, - .a = json_array (), - .hc = hc + .a = json_array () }; GNUNET_assert (NULL != ac.a); @@ -910,11 +887,7 @@ build_wire_state (void) json_decref (wire_fee_object); json_decref (wire_accounts_array); GNUNET_free (wire_method); - wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR; - wsh->wire_reply - = TALER_MHD_make_error (TALER_EC_GENERIC_DB_FETCH_FAILED, - "get_wire_fees"); - GNUNET_CRYPTO_hash_context_abort (hc); + wsh->ready = false; return wsh; } if (0 != json_array_size (ac.a)) @@ -939,65 +912,13 @@ build_wire_state (void) wads = json_array (); /* #7271 */ GNUNET_assert (NULL != wads); wsh->json_reply = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_incref ("accounts", - wire_accounts_array), - GNUNET_JSON_pack_array_incref ("wads", - wads), - GNUNET_JSON_pack_object_incref ("fees", - wire_fee_object)); - wsh->wire_reply = TALER_MHD_MAKE_JSON_PACK ( GNUNET_JSON_pack_array_steal ("accounts", wire_accounts_array), GNUNET_JSON_pack_array_steal ("wads", wads), GNUNET_JSON_pack_object_steal ("fees", - wire_fee_object), - GNUNET_JSON_pack_data_auto ("master_public_key", - &TEH_master_public_key)); - { - struct GNUNET_TIME_Timestamp m; - - m = GNUNET_TIME_absolute_to_timestamp (wsh->cache_expiration); - TALER_MHD_get_date_string (m.abs_time, - wsh->dat); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Setting 'Expires' header for '/wire' to '%s'\n", - wsh->dat); - GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, - MHD_HTTP_HEADER_EXPIRES, - wsh->dat)); - } - /* Set cache control headers: our response varies depending on these headers */ - GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, - MHD_HTTP_HEADER_VARY, - MHD_HTTP_HEADER_ACCEPT_ENCODING)); - /* Information is always public, revalidate after 1 day */ - GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, - MHD_HTTP_HEADER_CACHE_CONTROL, - "public,max-age=86400")); - - { - struct GNUNET_HashCode h; - char etag[sizeof (h) * 2]; - char *end; - - GNUNET_CRYPTO_hash_context_finish (hc, - &h); - end = GNUNET_STRINGS_data_to_string (&h, - sizeof (h), - etag, - sizeof (etag)); - *end = '\0'; - wsh->etag = GNUNET_strdup (etag); - GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, - MHD_HTTP_HEADER_ETAG, - etag)); - } - wsh->http_status = MHD_HTTP_OK; + wire_fee_object)); + wsh->ready = true; return wsh; } @@ -1185,12 +1106,20 @@ check_dk (void *cls, (void) cls; (void) hc; - GNUNET_assert (TALER_DENOMINATION_INVALID != dk->denom_pub.cipher); - if (TALER_DENOMINATION_RSA == dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) + { + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: GNUNET_assert (GNUNET_CRYPTO_rsa_public_key_check ( - dk->denom_pub.details.rsa_public_key)); - // nothing to do for TALER_DENOMINATION_CS - return GNUNET_OK; + dk->denom_pub.bsign_pub_key->details.rsa_public_key)); + return GNUNET_OK; + case GNUNET_CRYPTO_BSA_CS: + /* nothing to do for GNUNET_CRYPTO_BSA_CS */ + return GNUNET_OK; + } + GNUNET_assert (0); + return GNUNET_SYSERR; } @@ -1471,7 +1400,7 @@ load_age_mask (const char *section_name) * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_rsa hash of the @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bs_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -1483,7 +1412,7 @@ helper_rsa_cb ( struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_RsaPubHashP *h_rsa, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { @@ -1513,10 +1442,9 @@ helper_rsa_cb ( hd->validity_duration = validity_duration; hd->h_details.h_rsa = *h_rsa; hd->sm_sig = *sm_sig; - GNUNET_assert (TALER_DENOMINATION_RSA == denom_pub->cipher); - TALER_denom_pub_deep_copy (&hd->denom_pub, - denom_pub); - GNUNET_assert (TALER_DENOMINATION_RSA == hd->denom_pub.cipher); + GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == bs_pub->cipher); + hd->denom_pub.bsign_pub_key = + GNUNET_CRYPTO_bsign_pub_incref (bs_pub); /* load the age mask for the denomination, if applicable */ hd->denom_pub.age_mask = load_age_mask (section_name); TALER_denom_pub_hash (&hd->denom_pub, @@ -1552,7 +1480,7 @@ helper_rsa_cb ( * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_cs hash of the @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bs_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -1564,7 +1492,7 @@ helper_cs_cb ( struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_CsPubHashP *h_cs, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { @@ -1594,9 +1522,9 @@ helper_cs_cb ( hd->validity_duration = validity_duration; hd->h_details.h_cs = *h_cs; hd->sm_sig = *sm_sig; - GNUNET_assert (TALER_DENOMINATION_CS == denom_pub->cipher); - TALER_denom_pub_deep_copy (&hd->denom_pub, - denom_pub); + GNUNET_assert (GNUNET_CRYPTO_BSA_CS == bs_pub->cipher); + hd->denom_pub.bsign_pub_key + = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); /* load the age mask for the denomination, if applicable */ hd->denom_pub.age_mask = load_age_mask (section_name); TALER_denom_pub_hash (&hd->denom_pub, @@ -1975,7 +1903,8 @@ denomination_info_cb ( return; } - GNUNET_assert (TALER_DENOMINATION_INVALID != denom_pub->cipher); + GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != + denom_pub->bsign_pub_key->cipher); if (GNUNET_TIME_absolute_is_zero (meta->start.abs_time) || GNUNET_TIME_absolute_is_zero (meta->expire_withdraw.abs_time) || GNUNET_TIME_absolute_is_zero (meta->expire_deposit.abs_time) || @@ -2429,7 +2358,7 @@ create_krd (struct TEH_KeyStateHandle *ksh, json_t *keys; wsh = get_wire_state (); - if (MHD_HTTP_OK != wsh->http_status) + if (! wsh->ready) { GNUNET_break (0); return GNUNET_SYSERR; @@ -2678,12 +2607,12 @@ create_krd (struct TEH_KeyStateHandle *ksh, krd.response_compressed); /* Set cache control headers: our response varies depending on these headers */ GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, + MHD_add_response_header (krd.response_compressed, MHD_HTTP_HEADER_VARY, MHD_HTTP_HEADER_ACCEPT_ENCODING)); /* Information is always public, revalidate after 1 day */ GNUNET_break (MHD_YES == - MHD_add_response_header (wsh->wire_reply, + MHD_add_response_header (krd.response_compressed, MHD_HTTP_HEADER_CACHE_CONTROL, "public,max-age=86400")); GNUNET_break (MHD_YES == @@ -2902,22 +2831,48 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) { enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; json_t *recoup; - struct SignKeyCtx sctx; + struct SignKeyCtx sctx = { + .min_sk_frequency = GNUNET_TIME_UNIT_FOREVER_REL + }; json_t *grouped_denominations = NULL; struct GNUNET_TIME_Timestamp last_cherry_pick_date; struct GNUNET_CONTAINER_Heap *heap; struct SignatureContext sig_ctx = { 0 }; /* Remember if we have any denomination with age restriction */ bool has_age_restricted_denomination = false; + struct WireStateHandle *wsh; + wsh = get_wire_state (); + if (! wsh->ready) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (0 == + json_array_size (json_object_get (wsh->json_reply, + "accounts")) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "No wire accounts available. Refusing to generate /keys response.\n"); + return GNUNET_NO; + } sctx.signkeys = json_array (); GNUNET_assert (NULL != sctx.signkeys); - sctx.min_sk_frequency = GNUNET_TIME_UNIT_FOREVER_REL; + recoup = json_array (); + GNUNET_assert (NULL != recoup); + grouped_denominations = json_array (); + GNUNET_assert (NULL != grouped_denominations); + GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, &add_sign_key_cb, &sctx); - recoup = json_array (); - GNUNET_assert (NULL != recoup); + if (0 == json_array_size (sctx.signkeys)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "No online signing keys available. Refusing to generate /keys response.\n"); + ret = GNUNET_NO; + goto CLEANUP; + } heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); { struct DenomKeyCtx dkc = { @@ -2934,9 +2889,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) sctx.min_sk_frequency); } - grouped_denominations = json_array (); - GNUNET_assert (NULL != grouped_denominations); - last_cherry_pick_date = GNUNET_TIME_UNIT_ZERO_TS; { @@ -2995,7 +2947,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) json_t *entry; struct GNUNET_HashCode key; struct TALER_DenominationGroup meta = { - .cipher = dk->denom_pub.cipher, + .cipher = dk->denom_pub.bsign_pub_key->cipher, .value = dk->meta.value, .fees = dk->meta.fees, .age_mask = dk->meta.age_mask, @@ -3016,10 +2968,10 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) group = GNUNET_new (struct GroupData); switch (meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: cipher = age_restricted ? "RSA+age_restricted" : "RSA"; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: cipher = age_restricted ? "CS+age_restricted" : "CS"; break; default: @@ -3080,18 +3032,18 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) hd->validity_duration)); switch (meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: key_spec = GNUNET_JSON_pack_rsa_public_key ( "rsa_pub", - dk->denom_pub.details.rsa_public_key); + dk->denom_pub.bsign_pub_key->details.rsa_public_key); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: key_spec = GNUNET_JSON_pack_data_varsize ( "cs_pub", - &dk->denom_pub.details.cs_public_key, - sizeof (dk->denom_pub.details.cs_public_key)); + &dk->denom_pub.bsign_pub_key->details.cs_public_key, + sizeof (dk->denom_pub.bsign_pub_key->details.cs_public_key)); break; default: GNUNET_assert (false); @@ -3139,8 +3091,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) NULL); GNUNET_CONTAINER_multihashmap_destroy (denominations_by_group); } - GNUNET_CONTAINER_heap_destroy (heap); + if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) { struct GNUNET_HashCode hc; @@ -3189,7 +3141,8 @@ CLEANUP: sig_ctx.elements_size, 0); json_decref (grouped_denominations); - json_decref (sctx.signkeys); + if (NULL != sctx.signkeys) + json_decref (sctx.signkeys); json_decref (recoup); return ret; } @@ -3387,7 +3340,7 @@ build_key_state (struct HelperState *hs, finish_keys_response (ksh)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Could not finish /keys response (likely no signing keys available yet)\n"); + "Could not finish /keys response (required data not configured yet)\n"); destroy_key_state (ksh, true); return NULL; @@ -3564,17 +3517,21 @@ TEH_keys_denomination_sign ( &h_denom_pub->hash); if (NULL == hd) return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; - if (bp->cipher != hd->denom_pub.cipher) + if (bp->blinded_message->cipher != + hd->denom_pub.bsign_pub_key->cipher) return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - switch (hd->denom_pub.cipher) + switch (hd->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_RSA]++; { struct TALER_CRYPTO_RsaSignRequest rsr = { .h_rsa = &hd->h_details.h_rsa, - .msg = bp->details.rsa_blinded_planchet.blinded_msg, - .msg_size = bp->details.rsa_blinded_planchet.blinded_msg_size + .msg = bp->blinded_message->details.rsa_blinded_message.blinded_msg, + .msg_size = + bp->blinded_message->details.rsa_blinded_message.blinded_msg_size }; return TALER_CRYPTO_helper_rsa_sign ( @@ -3582,31 +3539,30 @@ TEH_keys_denomination_sign ( &rsr, bs); } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_CS]++; { struct TALER_CRYPTO_CsSignRequest csr; csr.h_cs = &hd->h_details.h_cs; - csr.blinded_planchet = &bp->details.cs_blinded_planchet; + csr.blinded_planchet = &bp->blinded_message->details.cs_blinded_message; return TALER_CRYPTO_helper_cs_sign ( ksh->helpers->csdh, &csr, for_melt, bs); } - default: - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } enum TALER_ErrorCode TEH_keys_denomination_batch_sign ( - const struct TEH_CoinSignData *csds, unsigned int csds_length, + const struct TEH_CoinSignData csds[static csds_length], bool for_melt, - struct TALER_BlindedDenominationSignature *bss) + struct TALER_BlindedDenominationSignature bss[static csds_length]) { struct TEH_KeyStateHandle *ksh; struct HelperDenomination *hd; @@ -3630,21 +3586,23 @@ TEH_keys_denomination_batch_sign ( &h_denom_pub->hash); if (NULL == hd) return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; - if (bp->cipher != hd->denom_pub.cipher) + if (bp->blinded_message->cipher != + hd->denom_pub.bsign_pub_key->cipher) return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - switch (hd->denom_pub.cipher) + switch (hd->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: rsrs[rsrs_pos].h_rsa = &hd->h_details.h_rsa; rsrs[rsrs_pos].msg - = bp->details.rsa_blinded_planchet.blinded_msg; + = bp->blinded_message->details.rsa_blinded_message.blinded_msg; rsrs[rsrs_pos].msg_size - = bp->details.rsa_blinded_planchet.blinded_msg_size; + = bp->blinded_message->details.rsa_blinded_message.blinded_msg_size; rsrs_pos++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: csrs[csrs_pos].h_cs = &hd->h_details.h_cs; - csrs[csrs_pos].blinded_planchet = &bp->details.cs_blinded_planchet; + csrs[csrs_pos].blinded_planchet + = &bp->blinded_message->details.cs_blinded_message; csrs_pos++; break; default: @@ -3667,8 +3625,8 @@ TEH_keys_denomination_batch_sign ( { ec = TALER_CRYPTO_helper_cs_batch_sign ( ksh->helpers->csdh, - csrs, csrs_pos, + csrs, for_melt, (0 == rsrs_pos) ? bss : cs); if (TALER_EC_NONE != ec) @@ -3683,8 +3641,8 @@ TEH_keys_denomination_batch_sign ( { ec = TALER_CRYPTO_helper_rsa_batch_sign ( ksh->helpers->rsadh, - rsrs, rsrs_pos, + rsrs, (0 == csrs_pos) ? bss : rs); if (TALER_EC_NONE != ec) { @@ -3706,12 +3664,12 @@ TEH_keys_denomination_batch_sign ( { const struct TALER_BlindedPlanchet *bp = csds[i].bp; - switch (bp->cipher) + switch (bp->blinded_message->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: bss[i] = rs[rsrs_pos++]; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: bss[i] = cs[csrs_pos++]; break; default: @@ -3727,10 +3685,10 @@ enum TALER_ErrorCode TEH_keys_denomination_cs_r_pub ( const struct TEH_CsDeriveData *cdd, bool for_melt, - struct TALER_DenominationCSPublicRPairP *r_pub) + struct GNUNET_CRYPTO_CSPublicRPairP *r_pub) { const struct TALER_DenominationHashP *h_denom_pub = cdd->h_denom_pub; - const struct TALER_CsNonce *nonce = cdd->nonce; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce = cdd->nonce; struct TEH_KeyStateHandle *ksh; struct HelperDenomination *hd; @@ -3745,7 +3703,8 @@ TEH_keys_denomination_cs_r_pub ( { return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; } - if (TALER_DENOMINATION_CS != hd->denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_CS != + hd->denom_pub.bsign_pub_key->cipher) { return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } @@ -3765,10 +3724,10 @@ TEH_keys_denomination_cs_r_pub ( enum TALER_ErrorCode TEH_keys_denomination_cs_batch_r_pub ( - const struct TEH_CsDeriveData *cdds, unsigned int cdds_length, + const struct TEH_CsDeriveData cdds[static cdds_length], bool for_melt, - struct TALER_DenominationCSPublicRPairP *r_pubs) + struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static cdds_length]) { struct TEH_KeyStateHandle *ksh; struct HelperDenomination *hd; @@ -3782,7 +3741,7 @@ TEH_keys_denomination_cs_batch_r_pub ( for (unsigned int i = 0; i<cdds_length; i++) { const struct TALER_DenominationHashP *h_denom_pub = cdds[i].h_denom_pub; - const struct TALER_CsNonce *nonce = cdds[i].nonce; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce = cdds[i].nonce; hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys, &h_denom_pub->hash); @@ -3790,7 +3749,8 @@ TEH_keys_denomination_cs_batch_r_pub ( { return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; } - if (TALER_DENOMINATION_CS != hd->denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_CS != + hd->denom_pub.bsign_pub_key->cipher) { return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } @@ -3799,8 +3759,8 @@ TEH_keys_denomination_cs_batch_r_pub ( } return TALER_CRYPTO_helper_cs_r_batch_derive (ksh->helpers->csdh, - cdrs, cdds_length, + cdrs, for_melt, r_pubs); } @@ -3825,22 +3785,23 @@ TEH_keys_denomination_revoke (const struct TALER_DenominationHashP *h_denom_pub) GNUNET_break (0); return; } - switch (hd->denom_pub.cipher) + switch (hd->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: TALER_CRYPTO_helper_rsa_revoke (ksh->helpers->rsadh, &hd->h_details.h_rsa); TEH_keys_update_states (); return; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TALER_CRYPTO_helper_cs_revoke (ksh->helpers->csdh, &hd->h_details.h_cs); TEH_keys_update_states (); return; - default: - GNUNET_break (0); - return; } + GNUNET_break (0); + return; } @@ -4170,7 +4131,8 @@ TEH_keys_load_fees (struct TEH_KeyStateHandle *ksh, meta); if (GNUNET_OK == ok) { - GNUNET_assert (TALER_DENOMINATION_INVALID != hd->denom_pub.cipher); + GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != + hd->denom_pub.bsign_pub_key->cipher); TALER_denom_pub_deep_copy (denom_pub, &hd->denom_pub); } @@ -4205,6 +4167,11 @@ TEH_keys_get_timing (const struct TALER_ExchangePublicKeyP *exchange_pub, pid.public_key = exchange_pub->eddsa_pub; hsk = GNUNET_CONTAINER_multipeermap_get (ksh->helpers->esign_keys, &pid); + if (NULL == hsk) + { + GNUNET_break (0); + return GNUNET_NO; + } meta->start = hsk->start_time; meta->expire_sign = GNUNET_TIME_absolute_to_timestamp ( diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index e170b978a..5baa8b307 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -325,10 +325,10 @@ TEH_keys_denomination_sign ( */ enum TALER_ErrorCode TEH_keys_denomination_batch_sign ( - const struct TEH_CoinSignData *csds, unsigned int csds_length, + const struct TEH_CoinSignData csds[static csds_length], bool for_melt, - struct TALER_BlindedDenominationSignature *bss); + struct TALER_BlindedDenominationSignature bss[static csds_length]); /** @@ -344,7 +344,7 @@ struct TEH_CsDeriveData /** * Nonce to use. */ - const struct TALER_CsNonce *nonce; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce; }; @@ -360,7 +360,7 @@ enum TALER_ErrorCode TEH_keys_denomination_cs_r_pub ( const struct TEH_CsDeriveData *cdd, bool for_melt, - struct TALER_DenominationCSPublicRPairP *r_pub); + struct GNUNET_CRYPTO_CSPublicRPairP *r_pub); /** @@ -375,10 +375,10 @@ TEH_keys_denomination_cs_r_pub ( */ enum TALER_ErrorCode TEH_keys_denomination_cs_batch_r_pub ( - const struct TEH_CsDeriveData *cdds, unsigned int cdds_length, + const struct TEH_CsDeriveData cdds[static cdds_length], bool for_melt, - struct TALER_DenominationCSPublicRPairP *r_pubs); + struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static cdds_length]); /** diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index 0ddc46916..0cf8ab727 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020, 2021 Taler Systems SA + Copyright (C) 2020-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -47,6 +47,16 @@ struct DenomSig */ struct TALER_MasterSignatureP master_sig; + /** + * Fee structure for this key, as per our configuration. + */ + struct TALER_EXCHANGEDB_DenominationKeyMetaData meta; + + /** + * The full public key. + */ + struct TALER_DenominationPublicKey denom_pub; + }; @@ -65,6 +75,11 @@ struct SigningSig */ struct TALER_MasterSignatureP master_sig; + /** + * Our meta data on this key. + */ + struct TALER_EXCHANGEDB_SignkeyMetaData meta; + }; @@ -128,14 +143,9 @@ add_keys (void *cls, { struct DenomSig *d = &akc->d_sigs[i]; enum GNUNET_DB_QueryStatus qs; - bool is_active = false; struct TALER_EXCHANGEDB_DenominationKeyMetaData meta; - struct TALER_DenominationPublicKey denom_pub; /* For idempotency, check if the key is already active */ - memset (&denom_pub, - 0, - sizeof (denom_pub)); qs = TEH_plugin->lookup_denomination_key ( TEH_plugin->cls, &d->h_denom_pub, @@ -151,66 +161,9 @@ add_keys (void *cls, "lookup denomination key"); return qs; } - if (0 == qs) - { - enum GNUNET_GenericReturnValue rv; - - rv = TEH_keys_load_fees (akc->ksh, - &d->h_denom_pub, - &denom_pub, - &meta); - switch (rv) - { - case GNUNET_SYSERR: - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, - GNUNET_h2s (&d->h_denom_pub.hash)); - return GNUNET_DB_STATUS_HARD_ERROR; - case GNUNET_NO: - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, - GNUNET_h2s (&d->h_denom_pub.hash)); - return GNUNET_DB_STATUS_HARD_ERROR; - case GNUNET_OK: - break; - } - } - else - { - is_active = true; - } - - /* check signature is valid */ - TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; - if (GNUNET_OK != - TALER_exchange_offline_denom_validity_verify ( - &d->h_denom_pub, - meta.start, - meta.expire_withdraw, - meta.expire_deposit, - meta.expire_legal, - &meta.value, - &meta.fees, - &TEH_master_public_key, - &d->master_sig)) - { - GNUNET_break_op (0); - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID, - GNUNET_h2s (&d->h_denom_pub.hash)); - if (! is_active) - TALER_denom_pub_free (&denom_pub); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - if (is_active) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { + /* FIXME: assert meta === d->meta might be good */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Denomination key %s already active, skipping\n", GNUNET_h2s (&d->h_denom_pub.hash)); @@ -220,10 +173,9 @@ add_keys (void *cls, qs = TEH_plugin->add_denomination_key ( TEH_plugin->cls, &d->h_denom_pub, - &denom_pub, - &meta, + &d->denom_pub, + &d->meta, &d->master_sig); - TALER_denom_pub_free (&denom_pub); if (qs < 0) { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) @@ -245,7 +197,6 @@ add_keys (void *cls, { struct SigningSig *s = &akc->s_sigs[i]; enum GNUNET_DB_QueryStatus qs; - bool is_active = false; struct TALER_EXCHANGEDB_SignkeyMetaData meta; qs = TEH_plugin->lookup_signing_key ( @@ -263,47 +214,9 @@ add_keys (void *cls, "lookup signing key"); return qs; } - if (0 == qs) - { - if (GNUNET_OK != - TEH_keys_get_timing (&s->exchange_pub, - &meta)) - { - /* For idempotency, check if the key is already active */ - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN, - TALER_B2S (&s->exchange_pub)); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } - else - { - is_active = true; /* if we pass, it's active! */ - } - - /* check signature is valid */ - TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; - if (GNUNET_OK != - TALER_exchange_offline_signkey_validity_verify ( - &s->exchange_pub, - meta.start, - meta.expire_sign, - meta.expire_legal, - &TEH_master_public_key, - &s->master_sig)) - { - GNUNET_break_op (0); - *mhd_ret = TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID, - TALER_B2S (&s->exchange_pub)); - return GNUNET_DB_STATUS_HARD_ERROR; - } - if (is_active) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { + /* FIXME: assert meta === d->meta might be good */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Signing key %s already active, skipping\n", TALER_B2S (&s->exchange_pub)); @@ -312,7 +225,7 @@ add_keys (void *cls, qs = TEH_plugin->activate_signing_key ( TEH_plugin->cls, &s->exchange_pub, - &meta, + &s->meta, &s->master_sig); if (qs < 0) { @@ -334,6 +247,25 @@ add_keys (void *cls, } +/** + * Clean up state in @a akc, but do not free @a akc itself + * + * @param[in,out] akc state to clean up + */ +static void +cleanup_akc (struct AddKeysContext *akc) +{ + for (unsigned int i = 0; i<akc->nd_sigs; i++) + { + struct DenomSig *d = &akc->d_sigs[i]; + + TALER_denom_pub_free (&d->denom_pub); + } + GNUNET_free (akc->d_sigs); + GNUNET_free (akc->s_sigs); +} + + MHD_RESULT TEH_handler_management_post_keys ( struct MHD_Connection *connection, @@ -349,7 +281,6 @@ TEH_handler_management_post_keys ( &signkey_sigs), GNUNET_JSON_spec_end () }; - bool ok; MHD_RESULT ret; { @@ -364,7 +295,8 @@ TEH_handler_management_post_keys ( return MHD_YES; /* failure */ } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Received /management/keys\n"); + "Received POST /management/keys request\n"); + akc.ksh = TEH_keys_get_state_for_management_only (); /* may start its own transaction, thus must be done here, before we run ours! */ if (NULL == akc.ksh) { @@ -375,10 +307,10 @@ TEH_handler_management_post_keys ( TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, "no key state (not even for management)"); } + akc.nd_sigs = json_array_size (denom_sigs); akc.d_sigs = GNUNET_new_array (akc.nd_sigs, struct DenomSig); - ok = true; for (unsigned int i = 0; i<akc.nd_sigs; i++) { struct DenomSig *d = &akc.d_sigs[i]; @@ -395,26 +327,64 @@ TEH_handler_management_post_keys ( json_array_get (denom_sigs, i), ispec); - if (GNUNET_SYSERR == res) + if (GNUNET_OK != res) { - ret = MHD_NO; /* hard failure */ - ok = false; - break; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failure to handle /management/keys\n"); + cleanup_akc (&akc); + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } - if (GNUNET_NO == res) + + res = TEH_keys_load_fees (akc.ksh, + &d->h_denom_pub, + &d->denom_pub, + &d->meta); + switch (res) { - ret = MHD_YES; - ok = false; + case GNUNET_SYSERR: + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, + GNUNET_h2s (&d->h_denom_pub.hash)); + cleanup_akc (&akc); + return ret; + case GNUNET_NO: + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, + GNUNET_h2s (&d->h_denom_pub.hash)); + cleanup_akc (&akc); + return ret; + case GNUNET_OK: break; } + /* check signature is valid */ + TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; + if (GNUNET_OK != + TALER_exchange_offline_denom_validity_verify ( + &d->h_denom_pub, + d->meta.start, + d->meta.expire_withdraw, + d->meta.expire_deposit, + d->meta.expire_legal, + &d->meta.value, + &d->meta.fees, + &TEH_master_public_key, + &d->master_sig)) + { + GNUNET_break_op (0); + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_KEYS_DENOMKEY_ADD_SIGNATURE_INVALID, + GNUNET_h2s (&d->h_denom_pub.hash)); + cleanup_akc (&akc); + return ret; + } } - if (! ok) - { - GNUNET_free (akc.d_sigs); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failure to handle /management/keys\n"); - return ret; - } + akc.ns_sigs = json_array_size (signkey_sigs); akc.s_sigs = GNUNET_new_array (akc.ns_sigs, struct SigningSig); @@ -434,26 +404,58 @@ TEH_handler_management_post_keys ( json_array_get (signkey_sigs, i), ispec); - if (GNUNET_SYSERR == res) + if (GNUNET_OK != res) { - ret = MHD_NO; /* hard failure */ - ok = false; - break; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failure to handle /management/keys\n"); + cleanup_akc (&akc); + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } - if (GNUNET_NO == res) + res = TEH_keys_get_timing (&s->exchange_pub, + &s->meta); + switch (res) { - ret = MHD_YES; - ok = false; + case GNUNET_SYSERR: + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, + TALER_B2S (&s->exchange_pub)); + cleanup_akc (&akc); + return ret; + case GNUNET_NO: + /* For idempotency, check if the key is already active */ + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_UNKNOWN, + TALER_B2S (&s->exchange_pub)); + cleanup_akc (&akc); + return ret; + case GNUNET_OK: break; } - } - if (! ok) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failure to handle /management/keys\n"); - GNUNET_free (akc.d_sigs); - GNUNET_free (akc.s_sigs); - return ret; + + /* check signature is valid */ + TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; + if (GNUNET_OK != + TALER_exchange_offline_signkey_validity_verify ( + &s->exchange_pub, + s->meta.start, + s->meta.expire_sign, + s->meta.expire_legal, + &TEH_master_public_key, + &s->master_sig)) + { + GNUNET_break_op (0); + ret = TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_EXCHANGE_MANAGEMENT_KEYS_SIGNKEY_ADD_SIGNATURE_INVALID, + TALER_B2S (&s->exchange_pub)); + cleanup_akc (&akc); + return ret; + } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received %u denomination and %u signing key signatures\n", @@ -468,8 +470,7 @@ TEH_handler_management_post_keys ( &ret, &add_keys, &akc); - GNUNET_free (akc.d_sigs); - GNUNET_free (akc.s_sigs); + cleanup_akc (&akc); if (GNUNET_SYSERR == res) return ret; } diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 1e5c92e18..f8aea95c5 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -338,12 +338,12 @@ check_melt_valid (struct MHD_Connection *connection, TALER_EC_EXCHANGE_MELT_FEES_EXCEED_CONTRIBUTION, NULL); } - switch (dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++; break; default: diff --git a/src/exchange/taler-exchange-httpd_recoup-refresh.c b/src/exchange/taler-exchange-httpd_recoup-refresh.c index d52dabda0..a5d5b2ab4 100644 --- a/src/exchange/taler-exchange-httpd_recoup-refresh.c +++ b/src/exchange/taler-exchange-httpd_recoup-refresh.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2017-2021 Taler Systems SA + Copyright (C) 2017-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -55,7 +55,7 @@ struct RecoupContext /** * Key used to blind the coin. */ - const union TALER_DenominationBlindingKeyP *coin_bks; + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks; /** * Signature of the coin requesting recoup. @@ -175,8 +175,8 @@ verify_and_execute_recoup_refresh ( struct MHD_Connection *connection, const struct TALER_CoinPublicInfo *coin, const struct TALER_ExchangeWithdrawValues *exchange_vals, - const union TALER_DenominationBlindingKeyP *coin_bks, - const struct TALER_CsNonce *nonce, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_CoinSpendSignatureP *coin_sig) { struct RecoupContext pc; @@ -219,12 +219,12 @@ verify_and_execute_recoup_refresh ( } /* check denomination signature */ - switch (dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++; break; default: @@ -265,6 +265,7 @@ verify_and_execute_recoup_refresh ( if (GNUNET_OK != TALER_denom_blind (&dk->denom_pub, coin_bks, + nonce, &coin->h_age_commitment, &coin->coin_pub, exchange_vals, @@ -278,9 +279,6 @@ verify_and_execute_recoup_refresh ( TALER_EC_EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED, NULL); } - if (TALER_DENOMINATION_CS == blinded_planchet.cipher) - blinded_planchet.details.cs_blinded_planchet.nonce - = *nonce; TALER_coin_ev_hash (&blinded_planchet, &coin->denom_pub_hash, &h_blind); @@ -375,10 +373,11 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection, { enum GNUNET_GenericReturnValue ret; struct TALER_CoinPublicInfo coin = {0}; - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; struct TALER_CoinSpendSignatureP coin_sig; struct TALER_ExchangeWithdrawValues exchange_vals; - struct TALER_CsNonce nonce; + union GNUNET_CRYPTO_BlindSessionNonce nonce; + bool no_nonce; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &coin.denom_pub_hash), @@ -394,19 +393,17 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection, GNUNET_JSON_spec_fixed_auto ("h_age_commitment", &coin.h_age_commitment), &coin.no_age_commitment), + // FIXME: rename to just 'nonce' GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_fixed_auto ("cs_nonce", &nonce), - NULL), + &no_nonce), GNUNET_JSON_spec_end () }; memset (&coin, 0, sizeof (coin)); - memset (&nonce, - 0, - sizeof (nonce)); coin.coin_pub = *coin_pub; ret = TALER_MHD_parse_json_data (connection, root, @@ -422,7 +419,9 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection, &coin, &exchange_vals, &coin_bks, - &nonce, + no_nonce + ? NULL + : &nonce, &coin_sig); GNUNET_JSON_parse_free (spec); return res; diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index 349c2b94a..6173ca6c9 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -58,7 +58,7 @@ struct RecoupContext /** * Key used to blind the coin. */ - const union TALER_DenominationBlindingKeyP *coin_bks; + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks; /** * Signature of the coin requesting recoup. @@ -178,8 +178,8 @@ verify_and_execute_recoup ( struct MHD_Connection *connection, const struct TALER_CoinPublicInfo *coin, const struct TALER_ExchangeWithdrawValues *exchange_vals, - const union TALER_DenominationBlindingKeyP *coin_bks, - const struct TALER_CsNonce *nonce, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_CoinSpendSignatureP *coin_sig) { struct RecoupContext pc; @@ -221,12 +221,12 @@ verify_and_execute_recoup ( } /* check denomination signature */ - switch (dk->denom_pub.cipher) + switch (dk->denom_pub.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++; break; default: @@ -270,6 +270,7 @@ verify_and_execute_recoup ( if (GNUNET_OK != TALER_denom_blind (&dk->denom_pub, coin_bks, + nonce, &coin->h_age_commitment, &coin->coin_pub, exchange_vals, @@ -283,9 +284,6 @@ verify_and_execute_recoup ( TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED, NULL); } - if (TALER_DENOMINATION_CS == blinded_planchet.cipher) - blinded_planchet.details.cs_blinded_planchet.nonce - = *nonce; if (GNUNET_OK != TALER_coin_ev_hash (&blinded_planchet, &coin->denom_pub_hash, @@ -388,10 +386,11 @@ TEH_handler_recoup (struct MHD_Connection *connection, { enum GNUNET_GenericReturnValue ret; struct TALER_CoinPublicInfo coin; - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; struct TALER_CoinSpendSignatureP coin_sig; struct TALER_ExchangeWithdrawValues exchange_vals; - struct TALER_CsNonce nonce; + union GNUNET_CRYPTO_BlindSessionNonce nonce; + bool no_nonce; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &coin.denom_pub_hash), @@ -407,19 +406,17 @@ TEH_handler_recoup (struct MHD_Connection *connection, GNUNET_JSON_spec_fixed_auto ("h_age_commitment", &coin.h_age_commitment), &coin.no_age_commitment), + // FIXME: should be renamed to just 'nonce'! GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_fixed_auto ("cs_nonce", &nonce), - NULL), + &no_nonce), GNUNET_JSON_spec_end () }; memset (&coin, 0, sizeof (coin)); - memset (&nonce, - 0, - sizeof (nonce)); coin.coin_pub = *coin_pub; ret = TALER_MHD_parse_json_data (connection, root, @@ -435,7 +432,9 @@ TEH_handler_recoup (struct MHD_Connection *connection, &coin, &exchange_vals, &coin_bks, - &nonce, + no_nonce + ? NULL + : &nonce, &coin_sig); GNUNET_JSON_parse_free (spec); return res; diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 81a086236..5630051cf 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -156,14 +156,17 @@ check_commitment (struct RevealContext *rctx, struct MHD_Connection *connection, MHD_RESULT *mhd_ret) { - struct TALER_CsNonce nonces[rctx->num_fresh_coins]; - unsigned int aoff = 0; + const union GNUNET_CRYPTO_BlindSessionNonce *nonces[rctx->num_fresh_coins]; + memset (nonces, + 0, + sizeof (nonces)); for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub; - if (dk->cipher != rctx->rcds[j].blinded_planchet.cipher) + if (dk->bsign_pub_key->cipher != + rctx->rcds[j].blinded_planchet.blinded_message->cipher) { GNUNET_break (0); *mhd_ret = TALER_MHD_reply_with_error ( @@ -173,9 +176,9 @@ check_commitment (struct RevealContext *rctx, NULL); return GNUNET_SYSERR; } - switch (dk->cipher) + switch (dk->bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_break (0); *mhd_ret = TALER_MHD_reply_with_error ( connection, @@ -183,44 +186,48 @@ check_commitment (struct RevealContext *rctx, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, NULL); return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: continue; - case TALER_DENOMINATION_CS: - nonces[aoff] - = rctx->rcds[j].blinded_planchet.details.cs_blinded_planchet.nonce; - aoff++; + case GNUNET_CRYPTO_BSA_CS: + nonces[j] + = (const union GNUNET_CRYPTO_BlindSessionNonce *) + &rctx->rcds[j].blinded_planchet.blinded_message->details. + cs_blinded_message.nonce; break; } } // OPTIMIZE: do this in batch later! - aoff = 0; for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub; struct TALER_ExchangeWithdrawValues *alg_values = &rctx->rrcs[j].exchange_vals; + struct GNUNET_CRYPTO_BlindingInputValues *bi; - alg_values->cipher = dk->cipher; - switch (dk->cipher) + bi = GNUNET_new (struct GNUNET_CRYPTO_BlindingInputValues); + alg_values->blinding_inputs = bi; + bi->rc = 1; + bi->cipher = dk->bsign_pub_key->cipher; + switch (dk->bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_assert (0); return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: continue; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { enum TALER_ErrorCode ec; const struct TEH_CsDeriveData cdd = { .h_denom_pub = &rctx->rrcs[j].h_denom_pub, - .nonce = &nonces[aoff] + .nonce = &nonces[j]->cs_nonce }; ec = TEH_keys_denomination_cs_r_pub ( &cdd, true, - &alg_values->details.cs_values); + &bi->details.cs_values); if (TALER_EC_NONE != ec) { *mhd_ret = TALER_MHD_reply_with_error (connection, @@ -229,7 +236,6 @@ check_commitment (struct RevealContext *rctx, NULL); return GNUNET_SYSERR; } - aoff++; } } } @@ -271,14 +277,11 @@ check_commitment (struct RevealContext *rctx, &ts); rce->new_coins = GNUNET_new_array (rctx->num_fresh_coins, struct TALER_RefreshCoinData); - aoff = 0; for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { - const struct TALER_DenominationPublicKey *dk - = &rctx->dks[j]->denom_pub; struct TALER_RefreshCoinData *rcd = &rce->new_coins[j]; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; const struct TALER_ExchangeWithdrawValues *alg_value = &rctx->rrcs[j].exchange_vals; struct TALER_PlanchetDetail pd = {0}; @@ -311,8 +314,9 @@ check_commitment (struct RevealContext *rctx, &acp, &ts.key, &nacp)); - - TALER_age_commitment_hash (&nacp.commitment, &h); + TALER_age_commitment_hash (&nacp.commitment, + &h); + TALER_age_commitment_proof_free (&nacp); hac = &h; } @@ -320,16 +324,11 @@ check_commitment (struct RevealContext *rctx, TALER_planchet_prepare (rcd->dk, alg_value, &bks, + nonces[j], &coin_priv, hac, &c_hash, &pd)); - if (TALER_DENOMINATION_CS == dk->cipher) - { - pd.blinded_planchet.details.cs_blinded_planchet.nonce = - nonces[aoff]; - aoff++; - } rcd->blinded_planchet = pd.blinded_planchet; } } @@ -539,7 +538,8 @@ resolve_refreshes_reveal_denominations ( &ret); if (NULL == dks[i]) return ret; - if ( (TALER_DENOMINATION_CS == dks[i]->denom_pub.cipher) && + if ( (GNUNET_CRYPTO_BSA_CS == + dks[i]->denom_pub.bsign_pub_key->cipher) && (rctx->no_rms) ) { return TALER_MHD_reply_with_error ( @@ -721,7 +721,8 @@ clean_age: rcd->blinded_planchet = rrc->blinded_planchet; rcd->dk = &dks[i]->denom_pub; - if (rcd->blinded_planchet.cipher != rcd->dk->cipher) + if (rcd->blinded_planchet.blinded_message->cipher != + rcd->dk->bsign_pub_key->cipher) { GNUNET_break_op (0); ret = TALER_MHD_REPLY_JSON_PACK ( @@ -758,8 +759,8 @@ clean_age: csds[i].bp = &rcds[i].blinded_planchet; } ec = TEH_keys_denomination_batch_sign ( - csds, rctx->num_fresh_coins, + csds, true, bss); if (TALER_EC_NONE != ec) @@ -862,7 +863,10 @@ cleanup: for (unsigned int i = 0; i<num_fresh_coins; i++) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i]; + struct TALER_ExchangeWithdrawValues *alg_values + = &rrcs[i].exchange_vals; + GNUNET_free (alg_values->blinding_inputs); TALER_blinded_denom_sig_free (&rrc->coin_sig); TALER_blinded_planchet_free (&rrc->blinded_planchet); } diff --git a/src/exchangedb/perf_deposits_get_ready.c b/src/exchangedb/perf_deposits_get_ready.c index f15665482..cba751e15 100644 --- a/src/exchangedb/perf_deposits_get_ready.c +++ b/src/exchangedb/perf_deposits_get_ready.c @@ -121,7 +121,7 @@ create_denom_key_pair (unsigned int size, GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dkp->priv, &dkp->pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, size)); memset (&dki, 0, @@ -202,8 +202,12 @@ run (void *cls) unsigned int *perm; unsigned long long duration_sq; struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_RSA, + .rc = 0 + }; struct TALER_ExchangeWithdrawValues alg_values = { - .cipher = TALER_DENOMINATION_RSA + .blinding_inputs = &bi }; ref = GNUNET_new_array (ROUNDS + 1, @@ -262,7 +266,7 @@ run (void *cls) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) { struct GNUNET_TIME_Timestamp now; - struct TALER_BlindedRsaPlanchet *rp; + struct GNUNET_CRYPTO_RsaBlindedMessage *rp; struct TALER_BlindedPlanchet *bp; now = GNUNET_TIME_timestamp_get (); @@ -274,8 +278,10 @@ run (void *cls) new_denom_pubs[cnt] = new_dkp[cnt]->pub; ccoin = &revealed_coins[cnt]; bp = &ccoin->blinded_planchet; - bp->cipher = TALER_DENOMINATION_RSA; - rp = &bp->details.rsa_blinded_planchet; + bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + bp->blinded_message->cipher = GNUNET_CRYPTO_BSA_RSA; + bp->blinded_message->rc = 1; + rp = &bp->blinded_message->details.rsa_blinded_message; rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( GNUNET_CRYPTO_QUALITY_WEAK, (RSA_KEY_SIZE / 8) - 1); @@ -315,7 +321,7 @@ run (void *cls) for (unsigned int j = 0; j < NUM_ROWS; j++) { /*** NEED TO INSERT REFRESH COMMITMENTS + ENSURECOIN ***/ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct GNUNET_TIME_Timestamp deadline; struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_ReservePublicKeyP reserve_pub; diff --git a/src/exchangedb/perf_get_link_data.c b/src/exchangedb/perf_get_link_data.c index eb1f5f6e2..817789afc 100644 --- a/src/exchangedb/perf_get_link_data.c +++ b/src/exchangedb/perf_get_link_data.c @@ -110,7 +110,7 @@ create_denom_key_pair (unsigned int size, GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dkp->priv, &dkp->pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, size)); memset (&dki, 0, @@ -208,8 +208,12 @@ run (void *cls) struct TALER_EXCHANGEDB_Refund *ref = NULL; unsigned int *perm; unsigned long long duration_sq; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_RSA, + .rc = 0 + }; struct TALER_ExchangeWithdrawValues alg_values = { - .cipher = TALER_DENOMINATION_RSA + .blinding_inputs = &bi }; ref = GNUNET_new_array (ROUNDS + 1, @@ -280,7 +284,7 @@ run (void *cls) "Transaction")); for (unsigned int j = 0; j < NUM_ROWS; j++) { - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_CoinPubHashP c_hash; unsigned int i = perm[j]; uint64_t known_coin_id; @@ -303,13 +307,16 @@ run (void *cls) struct TALER_EXCHANGEDB_RefreshRevealedCoin *revealed_coin = &revealed_coins[p]; struct TALER_BlindedPlanchet *bp = &revealed_coin->blinded_planchet; - struct TALER_BlindedRsaPlanchet *rp = &bp->details.rsa_blinded_planchet; + bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + struct GNUNET_CRYPTO_RsaBlindedMessage *rp = + &bp->blinded_message->details.rsa_blinded_message; /* h_coin_ev must be unique, but we only have MELT_NEW_COINS created above for NUM_ROWS iterations; instead of making "all new" coins, we simply randomize the hash here as nobody is checking for consistency anyway ;-) */ - bp->cipher = TALER_DENOMINATION_RSA; + bp->blinded_message->rc = 1; + bp->blinded_message->cipher = GNUNET_CRYPTO_BSA_RSA; rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( GNUNET_CRYPTO_QUALITY_WEAK, (RSA_KEY_SIZE / 8) - 1); diff --git a/src/exchangedb/perf_select_refunds_by_coin.c b/src/exchangedb/perf_select_refunds_by_coin.c index fdb44d2c9..8f2946fb8 100644 --- a/src/exchangedb/perf_select_refunds_by_coin.c +++ b/src/exchangedb/perf_select_refunds_by_coin.c @@ -117,7 +117,7 @@ create_denom_key_pair (unsigned int size, GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dkp->priv, &dkp->pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, size)); memset (&dki, 0, @@ -214,10 +214,14 @@ run (void *cls) struct TALER_EXCHANGEDB_CoinDepositInformation *depos = NULL; struct GNUNET_TIME_Timestamp deadline; struct TALER_Amount value; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_EXCHANGEDB_CollectableBlindcoin cbc; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_RSA, + .rc = 0 + }; struct TALER_ExchangeWithdrawValues alg_values = { - .cipher = TALER_DENOMINATION_RSA + .blinding_inputs = &bi }; struct GNUNET_TIME_Relative times = GNUNET_TIME_UNIT_ZERO; unsigned long long sqrs = 0; @@ -287,7 +291,7 @@ run (void *cls) for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++) { struct GNUNET_TIME_Timestamp now; - struct TALER_BlindedRsaPlanchet *rp; + struct GNUNET_CRYPTO_RsaBlindedMessage *rp; struct TALER_BlindedPlanchet *bp; now = GNUNET_TIME_timestamp_get (); @@ -299,8 +303,10 @@ run (void *cls) new_denom_pubs[cnt] = new_dkp[cnt]->pub; ccoin = &revealed_coins[cnt]; bp = &ccoin->blinded_planchet; - bp->cipher = TALER_DENOMINATION_RSA; - rp = &bp->details.rsa_blinded_planchet; + bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + bp->blinded_message->rc = 1; + bp->blinded_message->cipher = GNUNET_CRYPTO_BSA_RSA; + rp = &bp->blinded_message->details.rsa_blinded_message; rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( GNUNET_CRYPTO_QUALITY_WEAK, (RSA_KEY_SIZE / 8) - 1); diff --git a/src/exchangedb/pg_do_age_withdraw.c b/src/exchangedb/pg_do_age_withdraw.c index 99584098c..970e65b5d 100644 --- a/src/exchangedb/pg_do_age_withdraw.c +++ b/src/exchangedb/pg_do_age_withdraw.c @@ -82,6 +82,7 @@ TEH_PG_do_age_withdraw ( conflict), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; gc = GNUNET_TIME_absolute_to_timestamp ( GNUNET_TIME_absolute_add (now.abs_time, @@ -98,8 +99,10 @@ TEH_PG_do_age_withdraw ( ",conflict" " FROM exchange_do_age_withdraw" " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);"); - return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "call_age_withdraw", - params, - rs); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "call_age_withdraw", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; } diff --git a/src/exchangedb/pg_do_batch_withdraw_insert.c b/src/exchangedb/pg_do_batch_withdraw_insert.c index b95a179d2..758f502f2 100644 --- a/src/exchangedb/pg_do_batch_withdraw_insert.c +++ b/src/exchangedb/pg_do_batch_withdraw_insert.c @@ -29,7 +29,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_do_batch_withdraw_insert ( void *cls, - const struct TALER_CsNonce *nonce, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable, struct GNUNET_TIME_Timestamp now, uint64_t ruuid, diff --git a/src/exchangedb/pg_do_batch_withdraw_insert.h b/src/exchangedb/pg_do_batch_withdraw_insert.h index 6bc1a9a45..18fcfc9ae 100644 --- a/src/exchangedb/pg_do_batch_withdraw_insert.h +++ b/src/exchangedb/pg_do_batch_withdraw_insert.h @@ -41,7 +41,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_do_batch_withdraw_insert ( void *cls, - const struct TALER_CsNonce *nonce, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable, struct GNUNET_TIME_Timestamp now, uint64_t ruuid, diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c index 1e2d1c3c6..0ba45b628 100644 --- a/src/exchangedb/pg_do_deposit.c +++ b/src/exchangedb/pg_do_deposit.c @@ -87,6 +87,7 @@ TEH_PG_do_deposit ( ctr_conflict), GNUNET_PQ_result_spec_end }; + enum GNUNET_DB_QueryStatus qs; for (unsigned int i = 0; i < bd->num_cdis; i++) { @@ -109,8 +110,10 @@ TEH_PG_do_deposit ( ",out_conflict AS conflicted" " FROM exchange_do_deposit" " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16);"); - return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "call_deposit", - params, - rs); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "call_deposit", + params, + rs); + GNUNET_PQ_cleanup_query_params_closures (params); + return qs; } diff --git a/src/exchangedb/pg_do_recoup.c b/src/exchangedb/pg_do_recoup.c index 1f74104ed..07566a607 100644 --- a/src/exchangedb/pg_do_recoup.c +++ b/src/exchangedb/pg_do_recoup.c @@ -31,7 +31,7 @@ TEH_PG_do_recoup ( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, uint64_t reserve_out_serial_id, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, diff --git a/src/exchangedb/pg_do_recoup.h b/src/exchangedb/pg_do_recoup.h index 07a350789..2cf3eb976 100644 --- a/src/exchangedb/pg_do_recoup.h +++ b/src/exchangedb/pg_do_recoup.h @@ -45,7 +45,7 @@ TEH_PG_do_recoup ( void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, uint64_t reserve_out_serial_id, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, diff --git a/src/exchangedb/pg_do_recoup_refresh.c b/src/exchangedb/pg_do_recoup_refresh.c index be5e4705d..7d099bcd5 100644 --- a/src/exchangedb/pg_do_recoup_refresh.c +++ b/src/exchangedb/pg_do_recoup_refresh.c @@ -30,7 +30,7 @@ TEH_PG_do_recoup_refresh ( void *cls, const struct TALER_CoinSpendPublicKeyP *old_coin_pub, uint64_t rrc_serial, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, diff --git a/src/exchangedb/pg_do_recoup_refresh.h b/src/exchangedb/pg_do_recoup_refresh.h index fbd791d44..16b0fd208 100644 --- a/src/exchangedb/pg_do_recoup_refresh.h +++ b/src/exchangedb/pg_do_recoup_refresh.h @@ -46,7 +46,7 @@ TEH_PG_do_recoup_refresh ( void *cls, const struct TALER_CoinSpendPublicKeyP *old_coin_pub, uint64_t rrc_serial, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, diff --git a/src/exchangedb/pg_get_age_withdraw.c b/src/exchangedb/pg_get_age_withdraw.c index 6247fd14f..9a80f189b 100644 --- a/src/exchangedb/pg_get_age_withdraw.c +++ b/src/exchangedb/pg_get_age_withdraw.c @@ -61,22 +61,16 @@ TEH_PG_get_age_withdraw ( TALER_PQ_result_spec_array_blinded_denom_sig ( pg->conn, "denom_sigs", - NULL, /* we assume that this is the same size as h_coin_evs */ + NULL, /* FIXME-Oec: this assumes that this is the same size as h_coin_evs, but we should check! */ &aw->denom_sigs), TALER_PQ_result_spec_array_denom_hash ( pg->conn, "denom_pub_hashes", - NULL, /* we assume that this is the same size as h_coin_evs */ + NULL, /* FIXME-Oec: this assumes that this is the same size as h_coin_evs, but we should check! */ &aw->denom_pub_hashes), GNUNET_PQ_result_spec_end }; - GNUNET_assert (NULL != aw); - - /* Used in #postgres_get_age_withdraw() to - locate the response for a /reserve/$RESERVE_PUB/age-withdraw request - using the hash of the blinded message. Also needed to ensure - idempotency of /reserve/$RESERVE_PUB/age-withdraw requests. */ PREPARE (pg, "get_age_withdraw", "SELECT" diff --git a/src/exchangedb/pg_get_extension_manifest.c b/src/exchangedb/pg_get_extension_manifest.c index 5e95897d3..c6b5948cf 100644 --- a/src/exchangedb/pg_get_extension_manifest.c +++ b/src/exchangedb/pg_get_extension_manifest.c @@ -54,13 +54,12 @@ TEH_PG_get_extension_manifest (void *cls, }; *manifest = NULL; - /* Used in #postgres_get_extension_manifest */ PREPARE (pg, "get_extension_manifest", - "SELECT " - " manifest " - "FROM extensions" - " WHERE name=$1;"); + "SELECT" + " manifest" + " FROM extensions" + " WHERE name=$1;"); return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "get_extension_manifest", params, diff --git a/src/exchangedb/pg_get_known_coin.c b/src/exchangedb/pg_get_known_coin.c index bab48c119..2c4a82d67 100644 --- a/src/exchangedb/pg_get_known_coin.c +++ b/src/exchangedb/pg_get_known_coin.c @@ -51,9 +51,6 @@ TEH_PG_get_known_coin (void *cls, "Getting known coin data for coin %s\n", TALER_B2S (coin_pub)); coin_info->coin_pub = *coin_pub; - /* Used in #postgres_get_known_coin() to fetch - the denomination public key and signature for - a coin known to the exchange. */ PREPARE (pg, "get_known_coin", "SELECT" @@ -63,7 +60,6 @@ TEH_PG_get_known_coin (void *cls, " FROM known_coins" " JOIN denominations USING (denominations_serial)" " WHERE coin_pub=$1;"); - return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "get_known_coin", params, diff --git a/src/exchangedb/pg_get_link_data.c b/src/exchangedb/pg_get_link_data.c index 7fe6f996c..1b0cb3e20 100644 --- a/src/exchangedb/pg_get_link_data.c +++ b/src/exchangedb/pg_get_link_data.c @@ -69,6 +69,7 @@ free_link_data_list (struct TALER_EXCHANGEDB_LinkList *ldl) next = ldl->next; TALER_denom_pub_free (&ldl->denom_pub); TALER_blinded_denom_sig_free (&ldl->ev_sig); + TALER_denom_ewv_free (&ldl->alg_values); GNUNET_free (ldl); ldl = next; } @@ -147,9 +148,10 @@ add_ldl (void *cls, ldctx->status = GNUNET_SYSERR; return; } - if (TALER_DENOMINATION_CS == bp.cipher) + if (GNUNET_CRYPTO_BSA_CS == bp.blinded_message->cipher) { - pos->nonce = bp.details.cs_blinded_planchet.nonce; + pos->nonce.cs_nonce + = bp.blinded_message->details.cs_blinded_message.nonce; pos->have_nonce = true; } TALER_blinded_planchet_free (&bp); diff --git a/src/exchangedb/pg_get_refresh_reveal.c b/src/exchangedb/pg_get_refresh_reveal.c index 07d632248..08d4b21a5 100644 --- a/src/exchangedb/pg_get_refresh_reveal.c +++ b/src/exchangedb/pg_get_refresh_reveal.c @@ -112,7 +112,8 @@ add_revealed_coins (void *cls, GNUNET_PQ_result_spec_end }; - if (TALER_DENOMINATION_INVALID != rrc->blinded_planchet.cipher) + if (NULL != + rrc->blinded_planchet.blinded_message) { /* duplicate offset, not allowed */ GNUNET_break (0); @@ -205,6 +206,7 @@ cleanup: TALER_blinded_denom_sig_free (&rrc->coin_sig); TALER_blinded_planchet_free (&rrc->blinded_planchet); + TALER_denom_ewv_free (&rrc->exchange_vals); } GNUNET_free (grctx.rrcs); return qs; diff --git a/src/exchangedb/pg_insert_kyc_attributes.c b/src/exchangedb/pg_insert_kyc_attributes.c index bdddd020c..8b3cf84c6 100644 --- a/src/exchangedb/pg_insert_kyc_attributes.c +++ b/src/exchangedb/pg_insert_kyc_attributes.c @@ -99,9 +99,9 @@ TEH_PG_insert_kyc_attributes ( "insert_kyc_attributes", params, rs); + GNUNET_PQ_cleanup_query_params_closures (params); GNUNET_free (kyc_completed_notify_s); GNUNET_PQ_event_do_poll (pg->conn); - if (qs < 0) return qs; if (! ok) diff --git a/src/exchangedb/pg_lookup_denomination_key.c b/src/exchangedb/pg_lookup_denomination_key.c index 20eb703dd..a358528ad 100644 --- a/src/exchangedb/pg_lookup_denomination_key.c +++ b/src/exchangedb/pg_lookup_denomination_key.c @@ -60,7 +60,6 @@ TEH_PG_lookup_denomination_key ( GNUNET_PQ_result_spec_end }; - /* used in #postgres_lookup_denomination_key() */ PREPARE (pg, "lookup_denomination_key", "SELECT" diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c index 1b8540456..17cb496bf 100644 --- a/src/exchangedb/pg_reserves_in_insert.c +++ b/src/exchangedb/pg_reserves_in_insert.c @@ -246,6 +246,7 @@ TEH_PG_reserves_in_insert ( params, &helper_cb, &ctx); + GNUNET_PQ_cleanup_query_params_closures (params); if ( (qs < 0) || (GNUNET_OK != ctx.status) ) { diff --git a/src/exchangedb/pg_select_recoup_above_serial_id.c b/src/exchangedb/pg_select_recoup_above_serial_id.c index 2ff30c7dc..5791ee500 100644 --- a/src/exchangedb/pg_select_recoup_above_serial_id.c +++ b/src/exchangedb/pg_select_recoup_above_serial_id.c @@ -76,7 +76,7 @@ recoup_serial_helper_cb (void *cls, struct TALER_ReservePublicKeyP reserve_pub; struct TALER_CoinPublicInfo coin; struct TALER_CoinSpendSignatureP coin_sig; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_Amount amount; struct TALER_DenominationPublicKey denom_pub; struct TALER_BlindedCoinHashP h_blind_ev; diff --git a/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c b/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c index 22e09b46a..22f906738 100644 --- a/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c +++ b/src/exchangedb/pg_select_recoup_refresh_above_serial_id.c @@ -76,7 +76,7 @@ recoup_refresh_serial_helper_cb (void *cls, struct TALER_CoinSpendPublicKeyP old_coin_pub; struct TALER_CoinPublicInfo coin; struct TALER_CoinSpendSignatureP coin_sig; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_DenominationPublicKey denom_pub; struct TALER_DenominationHashP old_denom_pub_hash; struct TALER_Amount amount; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 336c14600..489f40ed1 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -278,7 +278,7 @@ create_denom_key_pair (unsigned int size, GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dkp->priv, &dkp->pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, size)); /* Using memset() as fields like master key and signature are not properly initialized for this test. */ @@ -1092,9 +1092,9 @@ recoup_cb (void *cls, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind) + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind) { - const union TALER_DenominationBlindingKeyP *cb = cls; + const union GNUNET_CRYPTO_BlindingSecretP *cb = cls; (void) rowid; (void) timestamp; @@ -1177,7 +1177,7 @@ run (void *cls) struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct TALER_CoinSpendSignatureP coin_sig; struct GNUNET_TIME_Timestamp deadline; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub2; struct TALER_ReservePublicKeyP reserve_pub3; @@ -1212,12 +1212,9 @@ run (void *cls) uint64_t reserve_out_serial_id; uint64_t melt_serial_id; struct TALER_PlanchetMasterSecretP ps; - union TALER_DenominationBlindingKeyP bks; - struct TALER_ExchangeWithdrawValues alg_values = { - /* RSA is simpler, and for the DB there is no real difference between - CS and RSA, just one should be used, so we use RSA */ - .cipher = TALER_DENOMINATION_RSA - }; + union GNUNET_CRYPTO_BlindingSecretP bks; + const struct TALER_ExchangeWithdrawValues *alg_values + = TALER_denom_ewv_rsa_singleton (); memset (&deposit, 0, @@ -1359,7 +1356,7 @@ run (void *cls) RND_BLK (&cbc.reserve_sig); RND_BLK (&ps); TALER_planchet_blinding_secret_create (&ps, - &alg_values, + alg_values, &bks); { struct TALER_PlanchetDetail pd; @@ -1380,9 +1377,10 @@ run (void *cls) GNUNET_assert (GNUNET_OK == TALER_denom_blind (&dkp->pub, &bks, + NULL, p_ah[i], &coin_pub, - &alg_values, + alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == @@ -1483,7 +1481,7 @@ run (void *cls) &cbc2.sig, &bks, &c_hash, - &alg_values, + alg_values, &dkp->pub)); FAILIF (GNUNET_OK != TALER_denom_pub_verify (&dkp->pub, @@ -1502,7 +1500,7 @@ run (void *cls) &cbc.sig, &bks, &c_hash, - &alg_values, + alg_values, &dkp->pub)); deadline = GNUNET_TIME_timestamp_get (); { @@ -1655,7 +1653,8 @@ run (void *cls) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct GNUNET_TIME_Timestamp now; - struct TALER_BlindedRsaPlanchet *rp; + struct GNUNET_CRYPTO_BlindedMessage *rp; + struct GNUNET_CRYPTO_RsaBlindedMessage *rsa; struct TALER_BlindedPlanchet *bp; now = GNUNET_TIME_timestamp_get (); @@ -1667,18 +1666,22 @@ run (void *cls) new_denom_pubs[cnt] = new_dkp[cnt]->pub; ccoin = &revealed_coins[cnt]; bp = &ccoin->blinded_planchet; - bp->cipher = TALER_DENOMINATION_RSA; - rp = &bp->details.rsa_blinded_planchet; - rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( + rp = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + bp->blinded_message = rp; + rp->cipher = GNUNET_CRYPTO_BSA_RSA; + rp->rc = 1; + rsa = &rp->details.rsa_blinded_message; + rsa->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 ( GNUNET_CRYPTO_QUALITY_WEAK, (RSA_KEY_SIZE / 8) - 1); - rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size); + rsa->blinded_msg = GNUNET_malloc (rsa->blinded_msg_size); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - rp->blinded_msg, - rp->blinded_msg_size); + rsa->blinded_msg, + rsa->blinded_msg_size); TALER_denom_pub_hash (&new_dkp[cnt]->pub, &ccoin->h_denom_pub); - ccoin->exchange_vals = alg_values; + TALER_denom_ewv_deep_copy (&ccoin->exchange_vals, + alg_values); TALER_coin_ev_hash (bp, &ccoin->h_denom_pub, &ccoin->coin_envelope_hash); @@ -1759,7 +1762,7 @@ run (void *cls) { struct GNUNET_TIME_Timestamp recoup_timestamp = GNUNET_TIME_timestamp_get (); - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; uint64_t new_known_coin_id; struct TALER_CoinPublicInfo new_coin; struct TALER_DenominationHashP dph; @@ -2129,7 +2132,7 @@ run (void *cls) &cbc.sig, &bks, &c_hash, - &alg_values, + alg_values, &dkp->pub)); RND_BLK (&deposit.csig); RND_BLK (&bd.merchant_pub); diff --git a/src/extensions/age_restriction/age_restriction.c b/src/extensions/age_restriction/age_restriction.c index 644a4ac6a..08b598d50 100644 --- a/src/extensions/age_restriction/age_restriction.c +++ b/src/extensions/age_restriction/age_restriction.c @@ -127,12 +127,13 @@ age_restriction_manifest ( GNUNET_JSON_pack_string ("age_groups", TALER_age_mask_to_string (&AR_config.mask)) ); - - return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_bool ("critical", ext->critical), - GNUNET_JSON_pack_string ("version", ext->version), - GNUNET_JSON_pack_object_steal ("config", conf) + GNUNET_JSON_pack_bool ("critical", + ext->critical), + GNUNET_JSON_pack_string ("version", + ext->version), + GNUNET_JSON_pack_object_steal ("config", + conf) ); } diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 9f9214c17..f6da2414e 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -610,24 +610,6 @@ enum TALER_MerchantConfirmationAlgorithm /** - * @brief Type of blinding keys for Taler. - * must be 32 bytes (DB) - */ -union TALER_DenominationBlindingKeyP -{ - /** - * Clause Schnorr Signatures have 2 blinding secrets, each containing two unpredictable values. (must be 32 bytes) - */ - struct GNUNET_CRYPTO_CsNonce nonce; - - /** - * Taler uses RSA for blind signatures. - */ - struct GNUNET_CRYPTO_RsaBlindingKeySecret rsa_bks; -}; - - -/** * Commitment value for the refresh protocol. * See #TALER_refresh_get_commitment(). */ @@ -1149,6 +1131,7 @@ void TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa, struct TALER_RsaPubHashP *h_rsa); + /** * Hash @a cs. * @@ -1161,75 +1144,16 @@ TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs, /** - * Types of public keys used for denominations in Taler. - */ -enum TALER_DenominationCipher -{ - - /** - * Invalid type of signature. - */ - TALER_DENOMINATION_INVALID = 0, - - /** - * RSA blind signature. - */ - TALER_DENOMINATION_RSA = 1, - - /** - * Clause Blind Schnorr signature. - */ - TALER_DENOMINATION_CS = 2 -}; - - -/** * @brief Type of (unblinded) coin signatures for Taler. */ struct TALER_DenominationSignature { - - /** - * Type of the signature. - */ - enum TALER_DenominationCipher cipher; - /** - * Details, depending on @e cipher. + * Denominations use blind signatures. */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct GNUNET_CRYPTO_CsSignature cs_signature; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct GNUNET_CRYPTO_RsaSignature *rsa_signature; - - } details; - + struct GNUNET_CRYPTO_UnblindedSignature *unblinded_sig; }; -/** - * The Sign Answer for Clause Blind Schnorr signature. - * The sign operation returns a parameter @param b and the signature - * scalar @param s_scalar. - */ -struct TALER_BlindedDenominationCsSignAnswer -{ - /** - * To make ROS problem harder, the signer chooses an unpredictable b and only calculates signature of c_b - */ - unsigned int b; - - /** - * The blinded s scalar calculated from c_b - */ - struct GNUNET_CRYPTO_CsBlindS s_scalar; -}; /** * @brief Type for *blinded* denomination signatures for Taler. @@ -1237,33 +1161,13 @@ struct TALER_BlindedDenominationCsSignAnswer */ struct TALER_BlindedDenominationSignature { - - /** - * Type of the signature. - */ - enum TALER_DenominationCipher cipher; - /** - * Details, depending on @e cipher. + * Denominations use blind signatures. */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - * At this point only the blinded s scalar is used. - * The final signature consisting of r,s is built after unblinding. - */ - struct TALER_BlindedDenominationCsSignAnswer blinded_cs_answer; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct GNUNET_CRYPTO_RsaSignature *blinded_rsa_signature; - - } details; - + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; }; + /* *************** Age Restriction *********************************** */ /* @@ -1322,31 +1226,15 @@ struct TALER_DenominationPublicKey { /** - * Type of the public key. - */ - enum TALER_DenominationCipher cipher; - - /** * Age restriction mask used for the key. */ struct TALER_AgeMask age_mask; /** - * Details, depending on @e cipher. + * Type of the public key. */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct GNUNET_CRYPTO_CsPublicKey cs_public_key; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct GNUNET_CRYPTO_RsaPublicKey *rsa_public_key; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub_key; - } details; }; @@ -1356,121 +1244,21 @@ struct TALER_DenominationPublicKey struct TALER_DenominationPrivateKey { - /** - * Type of the public key. - */ - enum TALER_DenominationCipher cipher; - - /** - * Details, depending on @e cipher. - */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct GNUNET_CRYPTO_CsPrivateKey cs_private_key; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct GNUNET_CRYPTO_RsaPrivateKey *rsa_private_key; + struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv_key; - } details; -}; - -/** - * @brief RSA Parameters to create blinded signature - * - */ -struct TALER_BlindedRsaPlanchet -{ - /** - * Blinded message to be signed - * Note: is malloc()'ed! - */ - void *blinded_msg; - - /** - * Size of the @e blinded_msg to be signed. - */ - size_t blinded_msg_size; -}; - - -/** - * Withdraw nonce for CS denominations - */ -struct TALER_CsNonce -{ - /** - * 32 bit nonce to include in withdrawals when using CS. - */ - struct GNUNET_CRYPTO_CsNonce nonce; -}; - - -/** - * @brief CS Parameters to create blinded signature - */ -struct TALER_BlindedCsPlanchet -{ - /** - * The Clause Schnorr c_0 and c_1 containing the blinded message - */ - struct GNUNET_CRYPTO_CsC c[2]; - - /** - * Public nonce. - */ - struct TALER_CsNonce nonce; }; /** - * @brief Type including Parameters to create blinded signature + * @brief Blinded planchet send to exchange for blind signing. */ struct TALER_BlindedPlanchet { /** - * Type of the sign blinded message - */ - enum TALER_DenominationCipher cipher; - - /** - * Details, depending on @e cipher. + * A blinded message. */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct TALER_BlindedCsPlanchet cs_blinded_planchet; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct TALER_BlindedRsaPlanchet rsa_blinded_planchet; - - } details; -}; - - -/** - * Pair of Public R values for Cs denominations - */ -struct TALER_DenominationCSPublicRPairP -{ - struct GNUNET_CRYPTO_CsRPublic r_pub[2]; -}; - + struct GNUNET_CRYPTO_BlindedMessage *blinded_message; -/** - * Secret r for Cs denominations - */ -struct TALER_DenominationCSPrivateRPairP -{ - struct GNUNET_CRYPTO_CsRSecret r[2]; }; @@ -1541,38 +1329,39 @@ struct TALER_TrackTransferDetails /** - * @brief Type of algorithm specific Values for withdrawal + * @brief Inputs needed from the exchange for blind signing. */ struct TALER_ExchangeWithdrawValues { /** - * Type of the signature. - */ - enum TALER_DenominationCipher cipher; - - /** - * Details, depending on @e cipher. + * Input values. */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct TALER_DenominationCSPublicRPairP cs_values; + struct GNUNET_CRYPTO_BlindingInputValues *blinding_inputs; +}; - } details; -}; +/** + * Return the alg value singleton for creation of + * blinding secrets for RSA. + * + * @return singleton to use for RSA blinding + */ +const struct TALER_ExchangeWithdrawValues * +TALER_denom_ewv_rsa_singleton (void); /** - * Free internals of @a denom_pub, but not @a denom_pub itself. + * Make a (deep) copy of the given @a bi_src to + * @a bi_dst. * - * @param[in] denom_pub key to free + * @param[out] bi_dst target to copy to + * @param bi_src blinding input values to copy */ void -TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub); +TALER_denom_ewv_deep_copy ( + struct TALER_ExchangeWithdrawValues *bi_dst, + const struct TALER_ExchangeWithdrawValues *bi_src); /** @@ -1597,7 +1386,7 @@ TALER_planchet_setup_coin_priv ( void TALER_cs_withdraw_nonce_derive ( const struct TALER_PlanchetMasterSecretP *ps, - struct TALER_CsNonce *nonce); + struct GNUNET_CRYPTO_CsSessionNonce *nonce); /** @@ -1612,13 +1401,13 @@ void TALER_cs_refresh_nonce_derive ( const struct TALER_RefreshMasterSecretP *rms, uint32_t idx, - struct TALER_CsNonce *nonce); + struct GNUNET_CRYPTO_CsSessionNonce *nonce); /** * Initialize denomination public-private key pair. * - * For #TALER_DENOMINATION_RSA, an additional "unsigned int" + * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" * argument with the number of bits for 'n' (e.g. 2048) must * be passed. * @@ -1631,11 +1420,29 @@ TALER_cs_refresh_nonce_derive ( enum GNUNET_GenericReturnValue TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv, struct TALER_DenominationPublicKey *denom_pub, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, ...); /** + * Free internals of @a denom_pub, but not @a denom_pub itself. + * + * @param[in] denom_pub key to free + */ +void +TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub); + + +/** + * Free internals of @a ewv, but not @a ewv itself. + * + * @param[in] ewv input values to free + */ +void +TALER_denom_ewv_free (struct TALER_ExchangeWithdrawValues *ewv); + + +/** * Free internals of @a denom_priv, but not @a denom_priv itself. * * @param[in] denom_priv key to free @@ -1662,6 +1469,8 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig); * * @param dk denomination public key to blind for * @param coin_bks blinding secret to use + * @param nonce nonce used to derive session values, + * could be NULL for ciphers that do not use it * @param age_commitment_hash hash of the age commitment to be used for the coin. NULL if no commitment is made. * @param coin_pub public key of the coin to blind * @param alg_values algorithm specific values to blind the planchet @@ -1671,7 +1480,8 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig); */ enum GNUNET_GenericReturnValue TALER_denom_blind (const struct TALER_DenominationPublicKey *dk, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_AgeCommitmentHash *age_commitment_hash, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_ExchangeWithdrawValues *alg_values, @@ -1710,7 +1520,7 @@ enum GNUNET_GenericReturnValue TALER_denom_sig_unblind ( struct TALER_DenominationSignature *denom_sig, const struct TALER_BlindedDenominationSignature *bdenom_sig, - const union TALER_DenominationBlindingKeyP *bks, + const union GNUNET_CRYPTO_BlindingSecretP *bks, const struct TALER_CoinPubHashP *c_hash, const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_DenominationPublicKey *denom_pub); @@ -1825,19 +1635,6 @@ TALER_blinded_planchet_cmp ( /** - * Obtain denomination public key from a denomination private key. - * - * @param denom_priv private key to convert - * @param age_mask age mask to be applied - * @param[out] denom_pub where to return the public key - */ -void -TALER_denom_priv_to_pub (const struct TALER_DenominationPrivateKey *denom_priv, - const struct TALER_AgeMask age_mask, - struct TALER_DenominationPublicKey *denom_pub); - - -/** * Verify signature made with a denomination public key * over a coin. * @@ -2152,7 +1949,7 @@ void TALER_planchet_blinding_secret_create ( const struct TALER_PlanchetMasterSecretP *ps, const struct TALER_ExchangeWithdrawValues *alg_values, - union TALER_DenominationBlindingKeyP *bks); + union GNUNET_CRYPTO_BlindingSecretP *bks); /** @@ -2161,6 +1958,7 @@ TALER_planchet_blinding_secret_create ( * @param dk denomination key for the coin to be created * @param alg_values algorithm specific values * @param bks blinding secrets + * @param nonce session nonce used to get @a alg_values * @param coin_priv coin private key * @param ach hash of age commitment to bind to this coin, maybe NULL * @param[out] c_hash set to the hash of the public key of the coin (needed later) @@ -2170,13 +1968,15 @@ TALER_planchet_blinding_secret_create ( * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue -TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, - const struct TALER_ExchangeWithdrawValues *alg_values, - const union TALER_DenominationBlindingKeyP *bks, - const struct TALER_CoinSpendPrivateKeyP *coin_priv, - const struct TALER_AgeCommitmentHash *ach, - struct TALER_CoinPubHashP *c_hash, - struct TALER_PlanchetDetail *pd); +TALER_planchet_prepare ( + const struct TALER_DenominationPublicKey *dk, + const struct TALER_ExchangeWithdrawValues *alg_values, + const union GNUNET_CRYPTO_BlindingSecretP *bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + const struct TALER_AgeCommitmentHash *ach, + struct TALER_CoinPubHashP *c_hash, + struct TALER_PlanchetDetail *pd); /** @@ -2216,7 +2016,7 @@ enum GNUNET_GenericReturnValue TALER_planchet_to_coin ( const struct TALER_DenominationPublicKey *dk, const struct TALER_BlindedDenominationSignature *blind_sig, - const union TALER_DenominationBlindingKeyP *bks, + const union GNUNET_CRYPTO_BlindingSecretP *bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_AgeCommitmentHash *ach, const struct TALER_CoinPubHashP *c_hash, @@ -2532,7 +2332,7 @@ typedef void struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_RsaPubHashP *h_rsa, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig); @@ -2633,9 +2433,9 @@ TALER_CRYPTO_helper_rsa_sign ( enum TALER_ErrorCode TALER_CRYPTO_helper_rsa_batch_sign ( struct TALER_CRYPTO_RsaDenominationHelper *dh, - const struct TALER_CRYPTO_RsaSignRequest *rsrs, unsigned int rsrs_length, - struct TALER_BlindedDenominationSignature *bss); + const struct TALER_CRYPTO_RsaSignRequest rsrs[static rsrs_length], + struct TALER_BlindedDenominationSignature bss[static rsrs_length]); /** @@ -2689,7 +2489,7 @@ struct TALER_CRYPTO_CsDenominationHelper; * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_cs hash of the CS @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bsign_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -2701,7 +2501,7 @@ typedef void struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_CsPubHashP *h_cs, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig); @@ -2747,7 +2547,8 @@ struct TALER_CRYPTO_CsSignRequest /** * Blinded planchet containing c and the nonce. */ - const struct TALER_BlindedCsPlanchet *blinded_planchet; + const struct GNUNET_CRYPTO_CsBlindedMessage *blinded_planchet; + }; @@ -2793,10 +2594,10 @@ TALER_CRYPTO_helper_cs_sign ( enum TALER_ErrorCode TALER_CRYPTO_helper_cs_batch_sign ( struct TALER_CRYPTO_CsDenominationHelper *dh, - const struct TALER_CRYPTO_CsSignRequest *reqs, unsigned int reqs_length, + const struct TALER_CRYPTO_CsSignRequest reqs[static reqs_length], bool for_melt, - struct TALER_BlindedDenominationSignature *bss); + struct TALER_BlindedDenominationSignature bss[static reqs_length]); /** @@ -2831,9 +2632,9 @@ struct TALER_CRYPTO_CsDeriveRequest const struct TALER_CsPubHashP *h_cs; /** - * Nonce to use. + * Nonce to use for the /csr request. */ - const struct TALER_CsNonce *nonce; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce; }; @@ -2858,7 +2659,7 @@ TALER_CRYPTO_helper_cs_r_derive ( struct TALER_CRYPTO_CsDenominationHelper *dh, const struct TALER_CRYPTO_CsDeriveRequest *cdr, bool for_melt, - struct TALER_DenominationCSPublicRPairP *crp); + struct GNUNET_CRYPTO_CSPublicRPairP *crp); /** @@ -2871,8 +2672,8 @@ TALER_CRYPTO_helper_cs_r_derive ( * differences in the signature counters. Retrying in this case may work. * * @param dh helper to process connection - * @param cdrs array with derivation input data * @param cdrs_length length of the @a cdrs array + * @param cdrs array with derivation input data * @param for_melt true if this is for a melt operation * @param[out] crps array set to the pair of R values, must be of length @a cdrs_length * @return set to the error code (or #TALER_EC_NONE on success) @@ -2880,10 +2681,10 @@ TALER_CRYPTO_helper_cs_r_derive ( enum TALER_ErrorCode TALER_CRYPTO_helper_cs_r_batch_derive ( struct TALER_CRYPTO_CsDenominationHelper *dh, - const struct TALER_CRYPTO_CsDeriveRequest *cdrs, unsigned int cdrs_length, + const struct TALER_CRYPTO_CsDeriveRequest cdrs[static cdrs_length], bool for_melt, - struct TALER_DenominationCSPublicRPairP *crps); + struct GNUNET_CRYPTO_CSPublicRPairP crps[static cdrs_length]); /** @@ -3797,7 +3598,7 @@ TALER_exchange_melt_confirmation_verify ( enum GNUNET_GenericReturnValue TALER_wallet_recoup_verify ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig); @@ -3813,7 +3614,7 @@ TALER_wallet_recoup_verify ( void TALER_wallet_recoup_sign ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig); @@ -3830,7 +3631,7 @@ TALER_wallet_recoup_sign ( enum GNUNET_GenericReturnValue TALER_wallet_recoup_refresh_verify ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig); @@ -3846,7 +3647,7 @@ TALER_wallet_recoup_refresh_verify ( void TALER_wallet_recoup_refresh_sign ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig); @@ -6059,7 +5860,7 @@ struct TALER_DenominationGroup /** * Cipher used for the denomination. */ - enum TALER_DenominationCipher cipher; + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Age mask for the denomiation. diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 44f43367a..8f5f4c4d2 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1513,6 +1513,7 @@ struct TALER_EXCHANGE_CsRWithdrawResponse * respective coin's withdraw operation. */ struct TALER_ExchangeWithdrawValues alg_values; + } ok; /** @@ -1558,7 +1559,7 @@ TALER_EXCHANGE_csr_withdraw ( struct GNUNET_CURL_Context *curl_ctx, const char *exchange_url, const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, TALER_EXCHANGE_CsRWithdrawCallback res_cb, void *res_cb_cls); @@ -1698,7 +1699,7 @@ struct TALER_EXCHANGE_CoinHistoryEntry { struct TALER_ReservePublicKeyP reserve_pub; struct GNUNET_TIME_Timestamp timestamp; - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; struct TALER_CoinSpendSignatureP coin_sig; @@ -1707,7 +1708,7 @@ struct TALER_EXCHANGE_CoinHistoryEntry struct { struct TALER_CoinSpendPublicKeyP old_coin_pub; - union TALER_DenominationBlindingKeyP coin_bks; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; struct GNUNET_TIME_Timestamp timestamp; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; @@ -2487,7 +2488,7 @@ struct TALER_EXCHANGE_PrivateCoinDetails * Value used to blind the key for the signature. * Needed for recoup operations. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Signature over the coin. @@ -2890,7 +2891,7 @@ struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails * Value used to blind the key for the signature. * Needed for recoup operations. */ - union TALER_DenominationBlindingKeyP blinding_key; + union GNUNET_CRYPTO_BlindingSecretP blinding_key; /** * The age commitment, proof for the coin, derived from the @@ -3464,7 +3465,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo /** * Blinding keys used to blind the fresh coin. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Signature affirming the validity of the coin. diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 252c27a7a..9d541ac12 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -569,7 +569,7 @@ struct TALER_EXCHANGEDB_TableData { struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendSignatureP coin_sig; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_Amount amount; struct GNUNET_TIME_Timestamp timestamp; uint64_t reserve_out_serial_id; @@ -580,7 +580,7 @@ struct TALER_EXCHANGEDB_TableData uint64_t known_coin_id; struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendSignatureP coin_sig; - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; struct TALER_Amount amount; struct GNUNET_TIME_Timestamp timestamp; uint64_t rrc_serial; @@ -1278,7 +1278,7 @@ struct TALER_EXCHANGEDB_Recoup * Blinding factor supplied to prove to the exchange that * the coin came from this reserve. */ - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; /** * Signature of the coin of type @@ -1332,7 +1332,7 @@ struct TALER_EXCHANGEDB_RecoupListEntry * Blinding factor supplied to prove to the exchange that * the coin came from this reserve. */ - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; /** * Signature of the coin of type @@ -1380,7 +1380,7 @@ struct TALER_EXCHANGEDB_RecoupRefreshListEntry * Blinding factor supplied to prove to the exchange that * the coin came from this @e old_coin_pub. */ - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; /** * Signature of the coin of type @@ -2423,9 +2423,9 @@ struct TALER_EXCHANGEDB_LinkList struct TALER_CoinSpendSignatureP orig_coin_link_sig; /** - * CS nonce, if cipher is CS. + * Session nonce, if cipher has one. */ - struct TALER_CsNonce nonce; + union GNUNET_CRYPTO_BlindSessionNonce nonce; /** * Offset that generated this coin in the refresh @@ -3245,7 +3245,7 @@ typedef enum GNUNET_GenericReturnValue const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind); + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind); /** @@ -3275,7 +3275,7 @@ typedef enum GNUNET_GenericReturnValue const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind); + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind); /** @@ -3388,7 +3388,7 @@ typedef void uint64_t rowid, const struct TALER_CoinPublicInfo *coin, const struct TALER_CoinSpendSignatureP *coin_sig, - const union TALER_DenominationBlindingKeyP *coin_blind, + const union GNUNET_CRYPTO_BlindingSecretP *coin_blind, const struct TALER_BlindedCoinHashP *h_blinded_ev, const struct TALER_Amount *amount); @@ -3855,7 +3855,7 @@ struct TALER_EXCHANGEDB_Plugin */ enum GNUNET_DB_QueryStatus (*lock_nonce)(void *cls, - const struct TALER_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, const struct TALER_DenominationHashP *denom_pub_hash, const union TALER_EXCHANGEDB_NonceLockTargetP *target); @@ -3936,7 +3936,7 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*do_batch_withdraw_insert)( void *cls, - const struct TALER_CsNonce *nonce, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable, struct GNUNET_TIME_Timestamp now, uint64_t ruuid, @@ -4100,7 +4100,7 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*cs_refreshes_reveal)( void *cls, - const struct TALER_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, const struct TALER_CoinSpendPublicKeyP *old_coin_pub, unsigned int num_fresh_coins, struct TALER_EXCHANGEDB_CsRevealFreshCoinData *crfcds); @@ -4153,7 +4153,7 @@ struct TALER_EXCHANGEDB_Plugin void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, uint64_t reserve_out_serial_id, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, @@ -4183,7 +4183,7 @@ struct TALER_EXCHANGEDB_Plugin void *cls, const struct TALER_CoinSpendPublicKeyP *old_coin_pub, uint64_t rrc_serial, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, uint64_t known_coin_id, const struct TALER_CoinSpendSignatureP *coin_sig, diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index a8da05e4c..1a1466700 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -366,7 +366,8 @@ TALER_JSON_spec_denom_pub (const char *field, */ struct GNUNET_JSON_Specification TALER_JSON_spec_denom_pub_cipher (const char *field, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm + cipher, struct TALER_DenominationPublicKey *pk); diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 72d70d00a..136967187 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -2732,7 +2732,7 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, op (refund_deadline, const struct GNUNET_TIME_Timestamp) \ op (exchange_pub, const struct TALER_ExchangePublicKeyP) \ op (exchange_sig, const struct TALER_ExchangeSignatureP) \ - op (blinding_key, const union TALER_DenominationBlindingKeyP) \ + op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP) \ op (h_blinded_coin, const struct TALER_BlindedCoinHashP) TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT) diff --git a/src/include/taler_util.h b/src/include/taler_util.h index 5f70bf65e..1ca019b99 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -226,12 +226,6 @@ struct TALER_CurrencySpecification char *name; /** - * Character used to separate decimals. String as - * multi-byte sequences may be required (UTF-8!). - */ - char *decimal_separator; - - /** * how many digits the user may enter at most after the @e decimal_separator */ unsigned int num_fractional_input_digits; diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 6c960353d..71291a9e5 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER 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 @@ -32,20 +32,20 @@ * @param cipher_s input string * @return numeric cipher value */ -static enum TALER_DenominationCipher +static enum GNUNET_CRYPTO_BlindSignatureAlgorithm string_to_cipher (const char *cipher_s) { if ((0 == strcasecmp (cipher_s, "RSA")) || (0 == strcasecmp (cipher_s, "RSA+age_restricted"))) - return TALER_DENOMINATION_RSA; + return GNUNET_CRYPTO_BSA_RSA; if ((0 == strcasecmp (cipher_s, "CS")) || (0 == strcasecmp (cipher_s, "CS+age_restricted"))) - return TALER_DENOMINATION_CS; - return TALER_DENOMINATION_INVALID; + return GNUNET_CRYPTO_BSA_CS; + return GNUNET_CRYPTO_BSA_INVALID; } @@ -164,7 +164,6 @@ parse_cspec (void *cls, struct TALER_CurrencySpecification *r_cspec = spec->ptr; const char *name; const char *currency; - const char *decimal_separator; uint32_t fid; uint32_t fnd; uint32_t ftzd; @@ -174,8 +173,6 @@ parse_cspec (void *cls, ¤cy), GNUNET_JSON_spec_string ("name", &name), - GNUNET_JSON_spec_string ("decimal_separator", - &decimal_separator), GNUNET_JSON_spec_uint32 ("num_fractional_input_digits", &fid), GNUNET_JSON_spec_uint32 ("num_fractional_normal_digits", @@ -236,7 +233,6 @@ parse_cspec (void *cls, return GNUNET_SYSERR; } r_cspec->name = GNUNET_strdup (name); - r_cspec->decimal_separator = GNUNET_strdup (decimal_separator); r_cspec->map_alt_unit_names = json_incref ((json_t *) map); return GNUNET_OK; } @@ -256,7 +252,6 @@ clean_cspec (void *cls, (void) cls; GNUNET_free (cspec->name); - GNUNET_free (cspec->decimal_separator); json_decref (cspec->map_alt_unit_names); } @@ -324,7 +319,7 @@ parse_denomination_group (void *cls, } group->cipher = string_to_cipher (cipher); - if (TALER_DENOMINATION_INVALID == group->cipher) + if (GNUNET_CRYPTO_BSA_INVALID == group->cipher) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -560,6 +555,7 @@ parse_denom_pub (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationPublicKey *denom_pub = spec->ptr; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; const char *cipher; bool age_mask_missing = false; struct GNUNET_JSON_Specification dspec[] = { @@ -587,16 +583,19 @@ parse_denom_pub (void *cls, if (age_mask_missing) denom_pub->age_mask.bits = 0; - - denom_pub->cipher = string_to_cipher (cipher); - switch (denom_pub->cipher) + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bsign_pub->rc = 1; + bsign_pub->cipher = string_to_cipher (cipher); + switch (bsign_pub->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_public_key ( "rsa_public_key", - &denom_pub->details.rsa_public_key), + &bsign_pub->details.rsa_public_key), GNUNET_JSON_spec_end () }; @@ -607,16 +606,18 @@ parse_denom_pub (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ("cs_public_key", - &denom_pub->details.cs_public_key, - sizeof (denom_pub->details.cs_public_key)), + &bsign_pub->details.cs_public_key, + sizeof (bsign_pub->details.cs_public_key)), GNUNET_JSON_spec_end () }; @@ -627,14 +628,16 @@ parse_denom_pub (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (bsign_pub); + return GNUNET_SYSERR; } @@ -666,7 +669,7 @@ TALER_JSON_spec_denom_pub (const char *field, .ptr = pk }; - pk->cipher = TALER_DENOMINATION_INVALID; + pk->bsign_pub_key = NULL; return ret; } @@ -676,7 +679,7 @@ TALER_JSON_spec_denom_pub (const char *field, * * Depending on the cipher in cls, it parses the corresponding public key type. * - * @param cls closure, enum TALER_DenominationCipher + * @param cls closure, enum GNUNET_CRYPTO_BlindSignatureAlgorithm * @param root the json object representing data * @param[out] spec where to write the data * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error @@ -687,19 +690,25 @@ parse_denom_pub_cipher (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationPublicKey *denom_pub = spec->ptr; - enum TALER_DenominationCipher cipher = - (enum TALER_DenominationCipher) (long) cls; + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher = + (enum GNUNET_CRYPTO_BlindSignatureAlgorithm) (long) cls; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; const char *emsg; unsigned int eline; + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bsign_pub->cipher = cipher; + bsign_pub->rc = 1; switch (cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_public_key ( "rsa_pub", - &denom_pub->details.rsa_public_key), + &bsign_pub->details.rsa_public_key), GNUNET_JSON_spec_end () }; @@ -710,17 +719,18 @@ parse_denom_pub_cipher (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } - denom_pub->cipher = cipher; + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ("cs_pub", - &denom_pub->details.cs_public_key, - sizeof (denom_pub->details.cs_public_key)), + &bsign_pub->details.cs_public_key, + sizeof (bsign_pub->details.cs_public_key)), GNUNET_JSON_spec_end () }; @@ -731,22 +741,23 @@ parse_denom_pub_cipher (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } - denom_pub->cipher = cipher; + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - default: - GNUNET_break_op (0); - denom_pub->cipher = 0; - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (bsign_pub); + return GNUNET_SYSERR; } struct GNUNET_JSON_Specification TALER_JSON_spec_denom_pub_cipher (const char *field, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm + cipher, struct TALER_DenominationPublicKey *pk) { struct GNUNET_JSON_Specification ret = { @@ -775,6 +786,7 @@ parse_denom_sig (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationSignature *denom_sig = spec->ptr; + struct GNUNET_CRYPTO_UnblindedSignature *unblinded_sig; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -794,15 +806,19 @@ parse_denom_sig (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - denom_sig->cipher = string_to_cipher (cipher); - switch (denom_sig->cipher) + unblinded_sig = GNUNET_new (struct GNUNET_CRYPTO_UnblindedSignature); + unblinded_sig->cipher = string_to_cipher (cipher); + unblinded_sig->rc = 1; + switch (unblinded_sig->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_signature ( "rsa_signature", - &denom_sig->details.rsa_signature), + &unblinded_sig->details.rsa_signature), GNUNET_JSON_spec_end () }; @@ -813,17 +829,21 @@ parse_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (unblinded_sig); return GNUNET_SYSERR; } + denom_sig->unblinded_sig = unblinded_sig; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("cs_signature_r", - &denom_sig->details.cs_signature.r_point), + &unblinded_sig->details.cs_signature. + r_point), GNUNET_JSON_spec_fixed_auto ("cs_signature_s", - &denom_sig->details.cs_signature.s_scalar), + &unblinded_sig->details.cs_signature. + s_scalar), GNUNET_JSON_spec_end () }; @@ -834,14 +854,16 @@ parse_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (unblinded_sig); return GNUNET_SYSERR; } + denom_sig->unblinded_sig = unblinded_sig; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (unblinded_sig); + return GNUNET_SYSERR; } @@ -873,7 +895,7 @@ TALER_JSON_spec_denom_sig (const char *field, .ptr = sig }; - sig->cipher = TALER_DENOMINATION_INVALID; + sig->unblinded_sig = NULL; return ret; } @@ -892,6 +914,7 @@ parse_blinded_denom_sig (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr; + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -911,15 +934,19 @@ parse_blinded_denom_sig (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - denom_sig->cipher = string_to_cipher (cipher); - switch (denom_sig->cipher) + blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blinded_sig->cipher = string_to_cipher (cipher); + blinded_sig->rc = 1; + switch (blinded_sig->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_signature ( "blinded_rsa_signature", - &denom_sig->details.blinded_rsa_signature), + &blinded_sig->details.blinded_rsa_signature), GNUNET_JSON_spec_end () }; @@ -930,17 +957,19 @@ parse_blinded_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_sig); return GNUNET_SYSERR; } + denom_sig->blinded_sig = blinded_sig; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_uint32 ("b", - &denom_sig->details.blinded_cs_answer.b), + &blinded_sig->details.blinded_cs_answer.b), GNUNET_JSON_spec_fixed_auto ("s", - &denom_sig->details.blinded_cs_answer. + &blinded_sig->details.blinded_cs_answer. s_scalar), GNUNET_JSON_spec_end () }; @@ -952,15 +981,16 @@ parse_blinded_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_sig); return GNUNET_SYSERR; } + denom_sig->blinded_sig = blinded_sig; return GNUNET_OK; } - break; - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (blinded_sig); + return GNUNET_SYSERR; } @@ -993,7 +1023,7 @@ TALER_JSON_spec_blinded_denom_sig ( .ptr = sig }; - sig->cipher = TALER_DENOMINATION_INVALID; + sig->blinded_sig = NULL; return ret; } @@ -1012,6 +1042,7 @@ parse_blinded_planchet (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_BlindedPlanchet *blinded_planchet = spec->ptr; + struct GNUNET_CRYPTO_BlindedMessage *blinded_message; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -1031,16 +1062,20 @@ parse_blinded_planchet (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - blinded_planchet->cipher = string_to_cipher (cipher); - switch (blinded_planchet->cipher) + blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + blinded_message->rc = 1; + blinded_message->cipher = string_to_cipher (cipher); + switch (blinded_message->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_varsize ( "rsa_blinded_planchet", - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size), + &blinded_message->details.rsa_blinded_message.blinded_msg, + &blinded_message->details.rsa_blinded_message.blinded_msg_size), GNUNET_JSON_spec_end () }; @@ -1051,22 +1086,24 @@ parse_blinded_planchet (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_message); return GNUNET_SYSERR; } + blinded_planchet->blinded_message = blinded_message; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ( "cs_nonce", - &blinded_planchet->details.cs_blinded_planchet.nonce), + &blinded_message->details.cs_blinded_message.nonce), GNUNET_JSON_spec_fixed_auto ( "cs_blinded_c0", - &blinded_planchet->details.cs_blinded_planchet.c[0]), + &blinded_message->details.cs_blinded_message.c[0]), GNUNET_JSON_spec_fixed_auto ( "cs_blinded_c1", - &blinded_planchet->details.cs_blinded_planchet.c[1]), + &blinded_message->details.cs_blinded_message.c[1]), GNUNET_JSON_spec_end () }; @@ -1077,15 +1114,16 @@ parse_blinded_planchet (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_message); return GNUNET_SYSERR; } + blinded_planchet->blinded_message = blinded_message; return GNUNET_OK; } - break; - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (blinded_message); + return GNUNET_SYSERR; } @@ -1117,7 +1155,7 @@ TALER_JSON_spec_blinded_planchet (const char *field, .ptr = blinded_planchet }; - blinded_planchet->cipher = TALER_DENOMINATION_INVALID; + blinded_planchet->blinded_message = NULL; return ret; } @@ -1136,6 +1174,7 @@ parse_exchange_withdraw_values (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_ExchangeWithdrawValues *ewv = spec->ptr; + struct GNUNET_CRYPTO_BlindingInputValues *bi; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -1155,21 +1194,26 @@ parse_exchange_withdraw_values (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - ewv->cipher = string_to_cipher (cipher); - switch (ewv->cipher) + bi = GNUNET_new (struct GNUNET_CRYPTO_BlindingInputValues); + bi->cipher = string_to_cipher (cipher); + bi->rc = 1; + switch (bi->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + ewv->blinding_inputs = bi; return GNUNET_OK; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ( "r_pub_0", - &ewv->details.cs_values.r_pub[0], + &bi->details.cs_values.r_pub[0], sizeof (struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_spec_fixed ( "r_pub_1", - &ewv->details.cs_values.r_pub[1], + &bi->details.cs_values.r_pub[1], sizeof (struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_spec_end () }; @@ -1181,14 +1225,34 @@ parse_exchange_withdraw_values (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bi); return GNUNET_SYSERR; } + ewv->blinding_inputs = bi; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (bi); + return GNUNET_SYSERR; +} + + +/** + * Cleanup data left from parsing withdraw values + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_exchange_withdraw_values ( + void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_ExchangeWithdrawValues *ewv = spec->ptr; + + (void) cls; + TALER_denom_ewv_free (ewv); } @@ -1199,11 +1263,12 @@ TALER_JSON_spec_exchange_withdraw_values ( { struct GNUNET_JSON_Specification ret = { .parser = &parse_exchange_withdraw_values, + .cleaner = &clean_exchange_withdraw_values, .field = field, .ptr = ewv }; - ewv->cipher = TALER_DENOMINATION_INVALID; + ewv->blinding_inputs = NULL; return ret; } diff --git a/src/json/json_pack.c b/src/json/json_pack.c index c6844c17b..71c8db9d2 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -101,37 +101,41 @@ TALER_JSON_pack_denom_pub ( const char *name, const struct TALER_DenominationPublicKey *pk) { + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == pk) return ps; - switch (pk->cipher) + bsp = pk->bsign_pub_key; + switch (bsp->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", "RSA"), + GNUNET_JSON_pack_string ("cipher", + "RSA"), GNUNET_JSON_pack_uint64 ("age_mask", pk->age_mask.bits), GNUNET_JSON_pack_rsa_public_key ("rsa_public_key", - pk->details.rsa_public_key)); - break; - case TALER_DENOMINATION_CS: + bsp->details.rsa_public_key)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", "CS"), + GNUNET_JSON_pack_string ("cipher", + "CS"), GNUNET_JSON_pack_uint64 ("age_mask", pk->age_mask.bits), GNUNET_JSON_pack_data_varsize ("cs_public_key", - &pk->details.cs_public_key, - sizeof (pk->details.cs_public_key))); - break; - default: - GNUNET_assert (0); + &bsp->details.cs_public_key, + sizeof (bsp->details.cs_public_key))); + return ps; } - + GNUNET_assert (0); return ps; } @@ -141,33 +145,36 @@ TALER_JSON_pack_denom_sig ( const char *name, const struct TALER_DenominationSignature *sig) { + const struct GNUNET_CRYPTO_UnblindedSignature *bs; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == sig) return ps; - switch (sig->cipher) + bs = sig->unblinded_sig; + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_rsa_signature ("rsa_signature", - sig->details.rsa_signature)); - break; - case TALER_DENOMINATION_CS: + bs->details.rsa_signature)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_auto ("cs_signature_r", - &sig->details.cs_signature.r_point), + &bs->details.cs_signature.r_point), GNUNET_JSON_pack_data_auto ("cs_signature_s", - &sig->details.cs_signature.s_scalar)); - break; - default: - GNUNET_assert (0); + &bs->details.cs_signature.s_scalar)); + return ps; } + GNUNET_assert (0); return ps; } @@ -177,36 +184,39 @@ TALER_JSON_pack_exchange_withdraw_values ( const char *name, const struct TALER_ExchangeWithdrawValues *ewv) { + const struct GNUNET_CRYPTO_BlindingInputValues *biv; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == ewv) return ps; - switch (ewv->cipher) + biv = ewv->blinding_inputs; + switch (biv->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA")); - break; - case TALER_DENOMINATION_CS: + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_varsize ( "r_pub_0", - &ewv->details.cs_values.r_pub[0], + &biv->details.cs_values.r_pub[0], sizeof(struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_pack_data_varsize ( "r_pub_1", - &ewv->details.cs_values.r_pub[1], + &biv->details.cs_values.r_pub[1], sizeof(struct GNUNET_CRYPTO_CsRPublic)) ); - break; - default: - GNUNET_assert (0); + return ps; } + GNUNET_assert (0); return ps; } @@ -216,33 +226,36 @@ TALER_JSON_pack_blinded_denom_sig ( const char *name, const struct TALER_BlindedDenominationSignature *sig) { + const struct GNUNET_CRYPTO_BlindedSignature *bs; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == sig) return ps; - switch (sig->cipher) + bs = sig->blinded_sig; + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature", - sig->details.blinded_rsa_signature)); - break; - case TALER_DENOMINATION_CS: + bs->details.blinded_rsa_signature)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_uint64 ("b", - sig->details.blinded_cs_answer.b), + bs->details.blinded_cs_answer.b), GNUNET_JSON_pack_data_auto ("s", - &sig->details.blinded_cs_answer.s_scalar)); - break; - default: - GNUNET_assert (0); + &bs->details.blinded_cs_answer.s_scalar)); + return ps; } + GNUNET_assert (0); return ps; } @@ -252,40 +265,43 @@ TALER_JSON_pack_blinded_planchet ( const char *name, const struct TALER_BlindedPlanchet *blinded_planchet) { + const struct GNUNET_CRYPTO_BlindedMessage *bm; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == blinded_planchet) return ps; - switch (blinded_planchet->cipher) + bm = blinded_planchet->blinded_message; + switch (bm->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_data_varsize ( "rsa_blinded_planchet", - blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size)); - break; - case TALER_DENOMINATION_CS: + bm->details.rsa_blinded_message.blinded_msg, + bm->details.rsa_blinded_message.blinded_msg_size)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_auto ( "cs_nonce", - &blinded_planchet->details.cs_blinded_planchet.nonce), + &bm->details.cs_blinded_message.nonce), GNUNET_JSON_pack_data_auto ( "cs_blinded_c0", - &blinded_planchet->details.cs_blinded_planchet.c[0]), + &bm->details.cs_blinded_message.c[0]), GNUNET_JSON_pack_data_auto ( "cs_blinded_c1", - &blinded_planchet->details.cs_blinded_planchet.c[1])); - break; - default: - GNUNET_assert (0); + &bm->details.cs_blinded_message.c[1])); + return ps; } + GNUNET_assert (0); return ps; } diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index 91ec901e9..3e98a956f 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -16,7 +16,10 @@ pkgcfg_DATA = \ bin_SCRIPTS = \ taler-exchange-kyc-kycaid-converter.sh \ - taler-exchange-kyc-persona-converter.sh + taler-exchange-kyc-persona-converter.sh \ + taler-exchange-kyc-oauth2-test-converter.sh \ + taler-exchange-kyc-oauth2-challenger.sh \ + taler-exchange-kyc-oauth2-nda.sh EXTRA_DIST = \ $(pkgcfg_DATA) \ diff --git a/src/kyclogic/kyclogic-oauth2.conf b/src/kyclogic/kyclogic-oauth2.conf index 61b38367f..57e1fc13a 100644 --- a/src/kyclogic/kyclogic-oauth2.conf +++ b/src/kyclogic/kyclogic-oauth2.conf @@ -29,7 +29,7 @@ KYC_OAUTH2_CLIENT_SECRET = password # Mustach template that converts OAuth2.0 data about the user # into GNU Taler standardized attribute data. # -# This is just an example, details will depend on the -# provider! +# This is just an example, you need to pick the right converter +# for the provider! # -KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"fullname":"{{last_name}}, {{first_name}}","phone":"{{phone}}"}"
\ No newline at end of file +KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-converter.sh diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c index c9e5d8dcf..5ef1330ad 100644 --- a/src/kyclogic/plugin_kyclogic_oauth2.c +++ b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -113,10 +113,10 @@ struct TALER_KYCLOGIC_ProviderDetails char *post_kyc_redirect_url; /** - * Template for converting user-data returned by - * the provider into our KYC attribute data. + * Name of the program we use to convert outputs + * from Persona into our JSON inputs. */ - char *attribute_template; + char *conversion_binary; /** * Validity time for a successful KYC process. @@ -188,6 +188,12 @@ struct TALER_KYCLOGIC_ProofHandle struct MHD_Connection *connection; /** + * Handle to an external process that converts the + * Persona response to our internal format. + */ + struct TALER_JSON_ExternalConversion *ec; + + /** * Hash of the payto URI that this is about. */ struct TALER_PaytoHashP h_payto; @@ -301,7 +307,7 @@ oauth2_unload_configuration (struct TALER_KYCLOGIC_ProviderDetails *pd) GNUNET_free (pd->client_id); GNUNET_free (pd->client_secret); GNUNET_free (pd->post_kyc_redirect_url); - GNUNET_free (pd->attribute_template); + GNUNET_free (pd->conversion_binary); GNUNET_free (pd); } @@ -336,6 +342,21 @@ oauth2_load_configuration (void *cls, oauth2_unload_configuration (pd); return NULL; } + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (ps->cfg, + provider_section_name, + "KYC_OAUTH2_CLIENT_ID", + &s)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + provider_section_name, + "KYC_OAUTH2_CLIENT_ID"); + oauth2_unload_configuration (pd); + return NULL; + } + pd->client_id = s; + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (ps->cfg, provider_section_name, @@ -414,9 +435,10 @@ oauth2_load_configuration (void *cls, pd->authorize_url = GNUNET_strndup (s, extra - s); GNUNET_asprintf (&pd->setup_url, - "%.*s/setup", + "%.*s/setup/%s", (int) (slash - s), - s); + s, + pd->client_id); GNUNET_free (s); } else @@ -457,20 +479,6 @@ oauth2_load_configuration (void *cls, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (ps->cfg, provider_section_name, - "KYC_OAUTH2_CLIENT_ID", - &s)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - provider_section_name, - "KYC_OAUTH2_CLIENT_ID"); - oauth2_unload_configuration (pd); - return NULL; - } - pd->client_id = s; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (ps->cfg, - provider_section_name, "KYC_OAUTH2_CLIENT_SECRET", &s)) { @@ -499,16 +507,14 @@ oauth2_load_configuration (void *cls, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (ps->cfg, provider_section_name, - "KYC_OAUTH2_ATTRIBUTE_TEMPLATE", - &s)) + "KYC_OAUTH2_CONVERTER_HELPER", + &pd->conversion_binary)) { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, provider_section_name, - "KYC_OAUTH2_ATTRIBUTE_TEMPLATE"); - } - else - { - pd->attribute_template = s; + "KYC_OAUTH2_CONVERTER_HELPER"); + oauth2_unload_configuration (pd); + return NULL; } return pd; @@ -547,18 +553,18 @@ initiate_with_url (struct TALER_KYCLOGIC_InitiateHandle *ih, char *redirect_uri; GNUNET_asprintf (&redirect_uri, - "%skyc-proof/%s?state=%s", + "%skyc-proof/%s", ps->exchange_base_url, - pd->section, - hps); + pd->section); redirect_uri_encoded = TALER_urlencode (redirect_uri); GNUNET_free (redirect_uri); } GNUNET_asprintf (&url, - "%s?response_type=code&client_id=%s&redirect_uri=%s", + "%s?response_type=code&client_id=%s&redirect_uri=%s&state=%s", authorize_url, pd->client_id, - redirect_uri_encoded); + redirect_uri_encoded, + hps); GNUNET_free (redirect_uri_encoded); } ih->cb (ih->cb_cls, @@ -628,7 +634,7 @@ handle_curl_setup_finished (void *cls, } GNUNET_asprintf (&url, "%s/%s", - pd->setup_url, + pd->authorize_url, nonce); initiate_with_url (ih, url); @@ -693,6 +699,22 @@ initiate_task (void *cls) curl_easy_setopt (eh, CURLOPT_URL, pd->setup_url)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POST, + 1)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDS, + "")); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_FOLLOWLOCATION, + 1L)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_MAXREDIRS, + 5L)); GNUNET_asprintf (&hdr, "%s: Bearer %s", MHD_HTTP_HEADER_AUTHORIZATION, @@ -773,6 +795,11 @@ oauth2_initiate_cancel (struct TALER_KYCLOGIC_InitiateHandle *ih) static void oauth2_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph) { + if (NULL != ph->ec) + { + TALER_JSON_external_conversion_stop (ph->ec); + ph->ec = NULL; + } if (NULL != ph->task) { GNUNET_SCHEDULER_cancel (ph->task); @@ -889,90 +916,26 @@ handle_proof_error (struct TALER_KYCLOGIC_ProofHandle *ph, /** - * Convert user data returned by the provider into - * standardized attribute data. - * - * @param pd our provider configuration - * @param data user-data given by the provider - * @return converted KYC attribute data object - */ -static json_t * -data2attributes (const struct TALER_KYCLOGIC_ProviderDetails *pd, - const json_t *data) -{ - json_t *ret; - void *attr_data; - size_t attr_size; - int rv; - json_error_t err; - - if (NULL == pd->attribute_template) - return json_object (); - if (0 != - (rv = TALER_TEMPLATING_fill (pd->attribute_template, - data, - &attr_data, - &attr_size))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to convert KYC provider data to attributes: %d\n", - rv); - json_dumpf (data, - stderr, - JSON_INDENT (2)); - return NULL; - } - ret = json_loadb (attr_data, - attr_size, - JSON_REJECT_DUPLICATES, - &err); - GNUNET_free (attr_data); - if (NULL == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse converted KYC attributes as JSON: %s (at offset %d)\n", - err.text, - err.position); - return NULL; - } - return ret; -} - - -/** - * The request for @a ph succeeded (presumably). - * Call continuation with the result. + * Type of a callback that receives a JSON @a result. * - * @param[in,out] ph request that succeeded - * @param j reply from the server + * @param cls closure with a `struct TALER_KYCLOGIC_ProofHandle *` + * @param status_type how did the process die + * @param code termination status code from the process + * @param attr result some JSON result, NULL if we failed to get an JSON output */ static void -parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, - const json_t *j) +converted_proof_cb (void *cls, + enum GNUNET_OS_ProcessStatusType status_type, + unsigned long code, + const json_t *attr) { - const char *state; - const json_t *data; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("status", - &state), - GNUNET_JSON_spec_object_const ("data", - &data), - GNUNET_JSON_spec_end () - }; - enum GNUNET_GenericReturnValue res; - const char *emsg; - unsigned int line; - - res = GNUNET_JSON_parse (j, - spec, - &emsg, - &line); - if (GNUNET_OK != res) + struct TALER_KYCLOGIC_ProofHandle *ph = cls; + + ph->ec = NULL; + if ( (NULL == attr) || + (0 != code) ) { GNUNET_break_op (0); - json_dumpf (j, - stderr, - JSON_INDENT (2)); ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; ph->response = TALER_MHD_make_error ( @@ -980,16 +943,11 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, "Unexpected response from KYC gateway: proof success must contain data and status"); ph->http_status = MHD_HTTP_BAD_GATEWAY; + ph->task = GNUNET_SCHEDULER_add_now (&return_proof_response, + ph); return; } - if (0 != strcasecmp (state, - "success")) - { - GNUNET_break_op (0); - handle_proof_error (ph, - j); - return; - } + { const char *id; struct GNUNET_JSON_Specification ispec[] = { @@ -997,15 +955,18 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, &id), GNUNET_JSON_spec_end () }; + enum GNUNET_GenericReturnValue res; + const char *emsg; + unsigned int line; - res = GNUNET_JSON_parse (data, + res = GNUNET_JSON_parse (attr, ispec, &emsg, &line); if (GNUNET_OK != res) { GNUNET_break_op (0); - json_dumpf (data, + json_dumpf (attr, stderr, JSON_INDENT (2)); ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; @@ -1017,21 +978,51 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, = MHD_HTTP_BAD_GATEWAY; return; } - ph->status = TALER_KYCLOGIC_STATUS_SUCCESS; - ph->response = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); - GNUNET_assert (NULL != ph->response); - GNUNET_break (MHD_YES == - MHD_add_response_header ( - ph->response, - MHD_HTTP_HEADER_LOCATION, - ph->pd->post_kyc_redirect_url)); - ph->http_status = MHD_HTTP_SEE_OTHER; ph->provider_user_id = GNUNET_strdup (id); } - ph->attributes = data2attributes (ph->pd, - data); + ph->status = TALER_KYCLOGIC_STATUS_SUCCESS; + ph->response = MHD_create_response_from_buffer (0, + "", + MHD_RESPMEM_PERSISTENT); + GNUNET_assert (NULL != ph->response); + GNUNET_break (MHD_YES == + MHD_add_response_header ( + ph->response, + MHD_HTTP_HEADER_LOCATION, + ph->pd->post_kyc_redirect_url)); + ph->http_status = MHD_HTTP_SEE_OTHER; + ph->attributes = json_incref ((json_t *) attr); + ph->task = GNUNET_SCHEDULER_add_now (&return_proof_response, + ph); +} + + +/** + * The request for @a ph succeeded (presumably). + * Call continuation with the result. + * + * @param[in,out] ph request that succeeded + * @param j reply from the server + */ +static void +parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, + const json_t *j) +{ + const struct TALER_KYCLOGIC_ProviderDetails *pd = ph->pd; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Calling converter `%s' with JSON\n", + pd->conversion_binary); + json_dumpf (j, + stderr, + JSON_INDENT (2)); + ph->ec = TALER_JSON_external_conversion_start ( + j, + &converted_proof_cb, + ph, + pd->conversion_binary, + pd->conversion_binary, + NULL); } @@ -1058,7 +1049,7 @@ handle_curl_proof_finished (void *cls, case MHD_HTTP_OK: parse_proof_success_reply (ph, j); - break; + return; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "OAuth2.0 info URL returned HTTP status %u\n", @@ -1321,10 +1312,9 @@ oauth2_proof (void *cls, char *redirect_uri; GNUNET_asprintf (&redirect_uri, - "%skyc-proof/%s?state=%s", + "%skyc-proof/%s", ps->exchange_base_url, - pd->section, - hps); + pd->section); redirect_uri_encoded = TALER_urlencode (redirect_uri); GNUNET_free (redirect_uri); } @@ -1342,9 +1332,10 @@ oauth2_proof (void *cls, 0); GNUNET_assert (NULL != authorization_code); GNUNET_asprintf (&ph->post_body, - "client_id=%s&redirect_uri=%s&client_secret=%s&code=%s&grant_type=authorization_code", + "client_id=%s&redirect_uri=%s&state=%s&client_secret=%s&code=%s&grant_type=authorization_code", client_id, redirect_uri_encoded, + hps, client_secret, authorization_code); curl_free (authorization_code); diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c index 406307838..7568af1f5 100644 --- a/src/kyclogic/plugin_kyclogic_persona.c +++ b/src/kyclogic/plugin_kyclogic_persona.c @@ -1022,6 +1022,12 @@ start_conversion (const struct TALER_KYCLOGIC_ProviderDetails *pd, TALER_JSON_JsonCallback cb, void *cb_cls) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Calling converter `%s' with JSON\n", + pd->conversion_binary); + json_dumpf (attr, + stderr, + JSON_INDENT (2)); return TALER_JSON_external_conversion_start ( attr, cb, diff --git a/src/kyclogic/taler-exchange-kyc-kycaid-converter.sh b/src/kyclogic/taler-exchange-kyc-kycaid-converter.sh index 96aca2b80..175a16137 100755 --- a/src/kyclogic/taler-exchange-kyc-kycaid-converter.sh +++ b/src/kyclogic/taler-exchange-kyc-kycaid-converter.sh @@ -78,7 +78,6 @@ then else # Combine into final result for business. echo "$J" | jq \ - --arg full_name "${FULLNAME}" \ $DOCS_RAW \ "{\"company_name\":.company_name,\"phone\":.phone,\"email\":.email,\"registration_country\":.registration_country,\"documents\":[${DOCS_JSON}]}" fi diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-challenger.sh b/src/kyclogic/taler-exchange-kyc-oauth2-challenger.sh new file mode 100755 index 000000000..729abc504 --- /dev/null +++ b/src/kyclogic/taler-exchange-kyc-oauth2-challenger.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# This file is in the public domain. +# +# This code converts (some of) the JSON output from +# Challenger into the GNU Taler +# specific KYC attribute data (again in JSON format). +# + +# Die if anything goes wrong. +set -eu + +# First, extract everything from stdin. +J=$(jq '{"id":.id,"email":.address,"type":.address_type,"expires":.address_expiration}') + +ADDRESS_TYPE=$(echo "$J" | jq -r '.type') +ROWID=$(echo "$J" | jq -r '.id') +if [ "$ADDRESS_TYPE" != "email" ] +then + return 1 +fi + +echo "$J" \ + | jq \ + --arg id "${ROWID}" \ + '{$id,"email":.email,"expires":.expires}' + +exit 0 diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-nda.sh b/src/kyclogic/taler-exchange-kyc-oauth2-nda.sh new file mode 100755 index 000000000..61c743c82 --- /dev/null +++ b/src/kyclogic/taler-exchange-kyc-oauth2-nda.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# This file is in the public domain. +# +# This code converts (some of) the JSON output from NDA into the GNU Taler +# specific KYC attribute data (again in JSON format). +# + +# Die if anything goes wrong. +set -eu + +# First, extract everything from stdin. +J=$(jq '{"status":.status,"id":.data.id,"last":.data.last_name,"first":.data.first_name,"phone":.data.phone}') + +STATUS=$(echo "$J" | jq -r '.status') +if [ "$STATUS" != "success" ] +then + return 1 +fi + +# Next, combine some fields into larger values. +FULLNAME=$(echo "$J" | jq -r '[.first_name,.last_name]|join(" ")') + +echo "$J" | jq \ + --arg full_name "${FULLNAME}" \ + '{$full_name,"phone":.phone,"id":.id}' + +exit 0 diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh b/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh new file mode 100755 index 000000000..3f7ff793d --- /dev/null +++ b/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# This file is in the public domain. +# +# This code converts (some of) the JSON output from +# Challenger into the GNU Taler +# specific KYC attribute data (again in JSON format). +# + +# Die if anything goes wrong. +set -eu + + +# First, extract everything from stdin. +J=$(jq '{"id":.data.id,"first":.data.first_name,"last":.data.last_name,"birthdate":.data.birthdate,"status":.status}') + +# Next, combine some fields into larger values. +STATUS=$(echo "$J" | jq -r '.status') +if [ "$STATUS" != "success" ] +then + return 1 +fi + +FULLNAME=$(echo "$J" | jq -r '[.first,.last]|join(" ")') + +echo $J | jq \ + --arg full_name "${FULLNAME}" \ + '{$full_name,"birthdate":.birthdate,"id":.id}' + +exit 0 diff --git a/src/lib/exchange_api_age_withdraw.c b/src/lib/exchange_api_age_withdraw.c index ea9c0371e..efa605aea 100644 --- a/src/lib/exchange_api_age_withdraw.c +++ b/src/lib/exchange_api_age_withdraw.c @@ -67,25 +67,40 @@ struct CoinCandidate */ struct CSRClosure { - /* Points to the actual candidate in CoinData.coin_candidates, to continue - * to build its contents based on the results from /csr-withdraw */ + /** + * Points to the actual candidate in CoinData.coin_candidates, to continue + * to build its contents based on the results from /csr-withdraw + */ struct CoinCandidate *candidate; - /* The planchet to finally generate. Points to the corresponding candidate - * in CoindData.planchet_details */ + /** + * The planchet to finally generate. Points to the corresponding candidate + * in CoindData.planchet_details + */ struct TALER_PlanchetDetail *planchet; - /* Handler to the originating call to /age-withdraw, needed to either + /** + * Handler to the originating call to /age-withdraw, needed to either * cancel the running age-withdraw request (on failure of the current call * to /csr-withdraw), or to eventually perform the protocol, once all - * csr-withdraw requests have successfully finished. */ + * csr-withdraw requests have successfully finished. + */ struct TALER_EXCHANGE_AgeWithdrawHandle *age_withdraw_handle; - /* Denomination information, needed for CS coins for the - * step after /csr-withdraw */ + /** + * Session nonce. + */ + union GNUNET_CRYPTO_BlindSessionNonce nonce; + + /** + * Denomination information, needed for CS coins for the + * step after /csr-withdraw + */ const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; - /* Handler for the CS R request */ + /** + * Handler for the CS R request + */ struct TALER_EXCHANGE_CsRWithdrawHandle *csr_withdraw_handle; }; @@ -663,13 +678,19 @@ copy_results ( struct TALER_EXCHANGE_AgeWithdrawResponse resp = { .hr = awbr->hr, .details = { - .ok = { .noreveal_index = awbr->details.ok.noreveal_index, - .h_commitment = awbr->details.ok.h_commitment, - .exchange_pub = awbr->details.ok.exchange_pub, - .num_coins = awh->num_coins, - .coin_details = details, - .blinded_coin_hs = blinded_coin_hs}, - }, + .ok = { + .noreveal_index = awbr->details.ok.noreveal_index, + .h_commitment = awbr->details.ok.h_commitment, + .exchange_pub = awbr->details.ok.exchange_pub, + .num_coins = awh->num_coins, + .coin_details = details, + .blinded_coin_hs = blinded_coin_hs + } + + + } + + }; for (size_t n = 0; n< awh->num_coins; n++) @@ -678,10 +699,8 @@ copy_results ( details[n].planchet = awh->coin_data[n].planchet_details[k]; blinded_coin_hs[n] = awh->coin_data[n].coin_candidates[k].blinded_coin_h; } - awh->callback (awh->callback_cls, &resp); - awh->callback = NULL; } @@ -794,9 +813,11 @@ csr_withdraw_done ( { bool success = false; /* Complete the initialization of the coin with CS denomination */ - can->details.alg_values = csrr->details.ok.alg_values; - GNUNET_assert (can->details.alg_values.cipher - == TALER_DENOMINATION_CS); + + TALER_denom_ewv_deep_copy (&can->details.alg_values, + &csrr->details.ok.alg_values); + GNUNET_assert (can->details.alg_values.blinding_inputs->cipher + == GNUNET_CRYPTO_BSA_CS); TALER_planchet_setup_coin_priv (&can->secret, &can->details.alg_values, &can->details.coin_priv); @@ -810,6 +831,7 @@ csr_withdraw_done ( TALER_planchet_prepare (&csr->denom_pub->key, &can->details.alg_values, &can->details.blinding_key, + &csr->nonce, &can->details.coin_priv, &can->details.h_age_commitment, &can->details.h_coin_pub, @@ -843,7 +865,6 @@ csr_withdraw_done ( default: break; } - TALER_EXCHANGE_age_withdraw_cancel (awh); } @@ -887,11 +908,10 @@ prepare_coins ( { struct CoinData *cd = &awh->coin_data[i]; const struct TALER_EXCHANGE_AgeWithdrawCoinInput *input = &coin_inputs[i]; - cd->denom_pub = *input->denom_pub; + cd->denom_pub = *input->denom_pub; /* The mask must be the same for all coins */ FAIL_IF (awh->age_mask.bits != input->denom_pub->key.age_mask.bits); - TALER_denom_pub_deep_copy (&cd->denom_pub.key, &input->denom_pub->key); @@ -912,35 +932,33 @@ prepare_coins ( TALER_age_commitment_hash (&can->details.age_commitment_proof.commitment, &can->details.h_age_commitment); - switch (input->denom_pub->key.cipher) + switch (input->denom_pub->key.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: - { - can->details.alg_values.cipher = TALER_DENOMINATION_RSA; - TALER_planchet_setup_coin_priv (&can->secret, - &can->details.alg_values, - &can->details.coin_priv); - TALER_planchet_blinding_secret_create (&can->secret, - &can->details.alg_values, - &can->details.blinding_key); - FAIL_IF (GNUNET_OK != - TALER_planchet_prepare (&cd->denom_pub.key, - &can->details.alg_values, - &can->details.blinding_key, - &can->details.coin_priv, - &can->details.h_age_commitment, - &can->details.h_coin_pub, - planchet)); - FAIL_IF (GNUNET_OK != - TALER_coin_ev_hash (&planchet->blinded_planchet, - &planchet->denom_pub_hash, - &can->blinded_coin_h)); - break; - } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_RSA: + TALER_denom_ewv_deep_copy (&can->details.alg_values, + TALER_denom_ewv_rsa_singleton ()); + TALER_planchet_setup_coin_priv (&can->secret, + &can->details.alg_values, + &can->details.coin_priv); + TALER_planchet_blinding_secret_create (&can->secret, + &can->details.alg_values, + &can->details.blinding_key); + FAIL_IF (GNUNET_OK != + TALER_planchet_prepare (&cd->denom_pub.key, + &can->details.alg_values, + &can->details.blinding_key, + NULL, + &can->details.coin_priv, + &can->details.h_age_commitment, + &can->details.h_coin_pub, + planchet)); + FAIL_IF (GNUNET_OK != + TALER_coin_ev_hash (&planchet->blinded_planchet, + &planchet->denom_pub_hash, + &can->blinded_coin_h)); + break; + case GNUNET_CRYPTO_BSA_CS: { - can->details.alg_values.cipher = TALER_DENOMINATION_CS; - struct CSRClosure *cls = &cd->csr_cls[k]; /** * Save the handler and the denomination for the callback @@ -949,21 +967,15 @@ prepare_coins ( cls->candidate = can; cls->planchet = planchet; cls->denom_pub = &cd->denom_pub; - TALER_cs_withdraw_nonce_derive ( &can->secret, - &planchet->blinded_planchet.details.cs_blinded_planchet.nonce); - - /* Note that we only initialize the first half - of the blinded_planchet here; the other part - will be done after the /csr-withdraw request! */ - planchet->blinded_planchet.cipher = TALER_DENOMINATION_CS; + &cls->nonce.cs_nonce); cls->csr_withdraw_handle = TALER_EXCHANGE_csr_withdraw ( awh->curl_ctx, awh->exchange_url, &cd->denom_pub, - &planchet->blinded_planchet.details.cs_blinded_planchet.nonce, + &cls->nonce.cs_nonce, &csr_withdraw_done, cls); FAIL_IF (NULL == cls->csr_withdraw_handle); @@ -1040,6 +1052,7 @@ TALER_EXCHANGE_age_withdraw_cancel ( { struct TALER_PlanchetDetail *planchet = &cd->planchet_details[k]; struct CSRClosure *cls = &cd->csr_cls[k]; + struct CoinCandidate *can = &cd->coin_candidates[k]; if (NULL != cls->csr_withdraw_handle) { @@ -1047,6 +1060,7 @@ TALER_EXCHANGE_age_withdraw_cancel ( cls->csr_withdraw_handle = NULL; } TALER_blinded_planchet_free (&planchet->blinded_planchet); + TALER_denom_ewv_free (&can->details.alg_values); } TALER_denom_pub_free (&cd->denom_pub.key); } diff --git a/src/lib/exchange_api_batch_withdraw.c b/src/lib/exchange_api_batch_withdraw.c index a1fcccce4..cd3286f3c 100644 --- a/src/lib/exchange_api_batch_withdraw.c +++ b/src/lib/exchange_api_batch_withdraw.c @@ -54,9 +54,14 @@ struct CoinData const struct TALER_AgeCommitmentHash *ach; /** - * blinding secret + * blinding secret */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; + + /** + * Session nonce. + */ + union GNUNET_CRYPTO_BlindSessionNonce nonce; /** * Private key of the coin we are withdrawing. @@ -79,7 +84,7 @@ struct CoinData struct TALER_CoinPubHashP c_hash; /** - * Handler for the CS R request (only used for TALER_DENOMINATION_CS denominations) + * Handler for the CS R request (only used for GNUNET_CRYPTO_BSA_CS denominations) */ struct TALER_EXCHANGE_CsRWithdrawHandle *csrh; @@ -111,7 +116,6 @@ struct TALER_EXCHANGE_BatchWithdrawHandle */ const struct TALER_EXCHANGE_Keys *keys; - /** * Handle for the actual (internal) batch withdraw operation. */ @@ -295,23 +299,24 @@ withdraw_cs_stage_two_callback ( }; cd->csrh = NULL; - GNUNET_assert (TALER_DENOMINATION_CS == cd->pk.key.cipher); + GNUNET_assert (GNUNET_CRYPTO_BSA_CS == + cd->pk.key.bsign_pub_key->cipher); switch (csrr->hr.http_status) { case MHD_HTTP_OK: - cd->alg_values = csrr->details.ok.alg_values; + TALER_denom_ewv_deep_copy (&cd->alg_values, + &csrr->details.ok.alg_values); TALER_planchet_setup_coin_priv (&cd->ps, &cd->alg_values, &cd->priv); TALER_planchet_blinding_secret_create (&cd->ps, &cd->alg_values, &cd->bks); - /* This initializes the 2nd half of the - wh->pd.blinded_planchet! */ if (GNUNET_OK != TALER_planchet_prepare (&cd->pk.key, &cd->alg_values, &cd->bks, + &cd->nonce, &cd->priv, cd->ach, &cd->c_hash, @@ -367,57 +372,51 @@ TALER_EXCHANGE_batch_withdraw ( cd->pk = *wci->pk; TALER_denom_pub_deep_copy (&cd->pk.key, &wci->pk->key); - switch (wci->pk->key.cipher) + switch (wci->pk->key.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: + TALER_denom_ewv_deep_copy (&cd->alg_values, + TALER_denom_ewv_rsa_singleton ()); + TALER_planchet_setup_coin_priv (&cd->ps, + &cd->alg_values, + &cd->priv); + TALER_planchet_blinding_secret_create (&cd->ps, + &cd->alg_values, + &cd->bks); + if (GNUNET_OK != + TALER_planchet_prepare (&cd->pk.key, + &cd->alg_values, + &cd->bks, + NULL, + &cd->priv, + cd->ach, + &cd->c_hash, + &cd->pd)) { - cd->alg_values.cipher = TALER_DENOMINATION_RSA; - TALER_planchet_setup_coin_priv (&cd->ps, - &cd->alg_values, - &cd->priv); - TALER_planchet_blinding_secret_create (&cd->ps, - &cd->alg_values, - &cd->bks); - if (GNUNET_OK != - TALER_planchet_prepare (&cd->pk.key, - &cd->alg_values, - &cd->bks, - &cd->priv, - cd->ach, - &cd->c_hash, - &cd->pd)) - { - GNUNET_break (0); - TALER_EXCHANGE_batch_withdraw_cancel (wh); - return NULL; - } - break; + GNUNET_break (0); + TALER_EXCHANGE_batch_withdraw_cancel (wh); + return NULL; } - case TALER_DENOMINATION_CS: + break; + case GNUNET_CRYPTO_BSA_CS: + TALER_cs_withdraw_nonce_derive ( + &cd->ps, + &cd->nonce.cs_nonce); + cd->csrh = TALER_EXCHANGE_csr_withdraw ( + curl_ctx, + exchange_url, + &cd->pk, + &cd->nonce.cs_nonce, + &withdraw_cs_stage_two_callback, + cd); + if (NULL == cd->csrh) { - TALER_cs_withdraw_nonce_derive ( - &cd->ps, - &cd->pd.blinded_planchet.details.cs_blinded_planchet.nonce); - /* Note that we only initialize the first half - of the blinded_planchet here; the other part - will be done after the /csr-withdraw request! */ - cd->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; - cd->csrh = TALER_EXCHANGE_csr_withdraw ( - curl_ctx, - exchange_url, - &cd->pk, - &cd->pd.blinded_planchet.details.cs_blinded_planchet.nonce, - &withdraw_cs_stage_two_callback, - cd); - if (NULL == cd->csrh) - { - GNUNET_break (0); - TALER_EXCHANGE_batch_withdraw_cancel (wh); - return NULL; - } - wh->cs_pending++; - break; + GNUNET_break (0); + TALER_EXCHANGE_batch_withdraw_cancel (wh); + return NULL; } + wh->cs_pending++; + break; default: GNUNET_break (0); TALER_EXCHANGE_batch_withdraw_cancel (wh); @@ -443,6 +442,7 @@ TALER_EXCHANGE_batch_withdraw_cancel ( TALER_EXCHANGE_csr_withdraw_cancel (cd->csrh); cd->csrh = NULL; } + TALER_denom_ewv_free (&cd->alg_values); TALER_blinded_planchet_free (&cd->pd.blinded_planchet); TALER_denom_pub_free (&cd->pk.key); } diff --git a/src/lib/exchange_api_csr_melt.c b/src/lib/exchange_api_csr_melt.c index f59995af3..1644f00a9 100644 --- a/src/lib/exchange_api_csr_melt.c +++ b/src/lib/exchange_api_csr_melt.c @@ -116,6 +116,8 @@ csr_ok (struct TALER_EXCHANGE_CsRMeltHandle *csrh, } csrh->cb (csrh->cb_cls, &csrr); + for (unsigned int i = 0; i<alen; i++) + TALER_denom_ewv_free (&alg_values[i]); return GNUNET_OK; } @@ -234,7 +236,8 @@ TALER_EXCHANGE_csr_melt ( return NULL; } for (unsigned int i = 0; i<nks_len; i++) - if (TALER_DENOMINATION_CS != nks[i].pk->key.cipher) + if (GNUNET_CRYPTO_BSA_CS != + nks[i].pk->key.bsign_pub_key->cipher) { GNUNET_break (0); return NULL; diff --git a/src/lib/exchange_api_csr_withdraw.c b/src/lib/exchange_api_csr_withdraw.c index 4c1d83a9a..0fe731cd5 100644 --- a/src/lib/exchange_api_csr_withdraw.c +++ b/src/lib/exchange_api_csr_withdraw.c @@ -105,6 +105,7 @@ csr_ok (struct TALER_EXCHANGE_CsRWithdrawHandle *csrh, } csrh->cb (csrh->cb_cls, &csrr); + TALER_denom_ewv_free (&csrr.details.ok.alg_values); return GNUNET_OK; } @@ -203,13 +204,14 @@ TALER_EXCHANGE_csr_withdraw ( struct GNUNET_CURL_Context *curl_ctx, const char *exchange_url, const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, TALER_EXCHANGE_CsRWithdrawCallback res_cb, void *res_cb_cls) { struct TALER_EXCHANGE_CsRWithdrawHandle *csrh; - if (TALER_DENOMINATION_CS != pk->key.cipher) + if (GNUNET_CRYPTO_BSA_CS != + pk->key.bsign_pub_key->cipher) { GNUNET_break (0); return NULL; @@ -233,10 +235,10 @@ TALER_EXCHANGE_csr_withdraw ( req = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_varsize ("nonce", nonce, - sizeof(struct TALER_CsNonce)), + sizeof(*nonce)), GNUNET_JSON_pack_data_varsize ("denom_pub_hash", &pk->h_key, - sizeof(struct TALER_DenominationHashP))); + sizeof(pk->h_key))); GNUNET_assert (NULL != req); eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url); if ( (NULL == eh) || @@ -265,8 +267,8 @@ TALER_EXCHANGE_csr_withdraw ( void -TALER_EXCHANGE_csr_withdraw_cancel (struct - TALER_EXCHANGE_CsRWithdrawHandle *csrh) +TALER_EXCHANGE_csr_withdraw_cancel ( + struct TALER_EXCHANGE_CsRWithdrawHandle *csrh) { if (NULL != csrh->job) { diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 50a1a9ce9..410c01245 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -458,7 +458,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key, static enum GNUNET_GenericReturnValue parse_json_denomkey_partially ( struct TALER_EXCHANGE_DenomPublicKey *denom_key, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, bool check_sigs, const json_t *denom_key_obj, struct TALER_MasterPublicKeyP *master_key, @@ -1111,7 +1111,6 @@ decode_keys_json (const json_t *resp_obj, denomination. Required to make the validity check inside parse_json_denomkey_partially pass */ struct TALER_EXCHANGE_DenomPublicKey dk = { - .key.cipher = group.cipher, .value = group.value, .fees = group.fees, .key.age_mask = group.age_mask @@ -1872,6 +1871,8 @@ TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys) free_fees (keys->fees, keys->fees_len); json_decref (keys->extensions); + GNUNET_free (keys->cspec.name); + json_decref (keys->cspec.map_alt_unit_names); GNUNET_free (keys->wallet_balance_limit_without_kyc); GNUNET_free (keys->version); GNUNET_free (keys->currency); @@ -1978,10 +1979,10 @@ add_grp (void *cls, (void) key; switch (gd->meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: cipher = age_restricted ? "RSA+age_restricted" : "RSA"; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: cipher = age_restricted ? "CS+age_restricted" : "CS"; break; default: @@ -2125,7 +2126,7 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) { const struct TALER_EXCHANGE_DenomPublicKey *dk = &kd->denom_keys[i]; struct TALER_DenominationGroup meta = { - .cipher = dk->key.cipher, + .cipher = dk->key.bsign_pub_key->cipher, .value = dk->value, .fees = dk->fees, .age_mask = dk->key.age_mask @@ -2159,18 +2160,18 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) } switch (meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: key_spec = GNUNET_JSON_pack_rsa_public_key ( "rsa_pub", - dk->key.details.rsa_public_key); + dk->key.bsign_pub_key->details.rsa_public_key); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: key_spec = GNUNET_JSON_pack_data_varsize ( "cs_pub", - &dk->key.details.cs_public_key, - sizeof (dk->key.details.cs_public_key)); + &dk->key.bsign_pub_key->details.cs_public_key, + sizeof (dk->key.bsign_pub_key->details.cs_public_key)); break; default: GNUNET_assert (false); diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c index f408b87d0..2d56ec915 100644 --- a/src/lib/exchange_api_link.c +++ b/src/lib/exchange_api_link.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2021 Taler Systems SA + Copyright (C) 2015-2023 Taler Systems SA TALER 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 @@ -89,9 +89,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, struct TALER_BlindedDenominationSignature bsig; struct TALER_DenominationPublicKey rpub; struct TALER_CoinSpendSignatureP link_sig; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_ExchangeWithdrawValues alg_values; - struct TALER_CsNonce nonce; + union GNUNET_CRYPTO_BlindSessionNonce nonce; bool no_nonce; uint32_t coin_idx; struct GNUNET_JSON_Specification spec[] = { @@ -163,6 +163,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, &rpub, &alg_values, &bks, + no_nonce + ? NULL + : &nonce, &lci->coin_priv, pah, &c_hash, @@ -172,16 +175,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - if (TALER_DENOMINATION_CS == alg_values.cipher) - { - if (no_nonce) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonce; - } /* extract coin and signature */ if (GNUNET_OK != TALER_denom_sig_unblind (&lci->sig, diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c index 03339c663..b88ddc205 100644 --- a/src/lib/exchange_api_management_get_keys.c +++ b/src/lib/exchange_api_management_get_keys.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015-2020 Taler Systems SA + Copyright (C) 2015-2023 Taler Systems SA TALER 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 @@ -228,14 +228,15 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, TALER_denom_pub_hash (&denom_key->key, &h_denom_pub); - switch (denom_key->key.cipher) + switch (denom_key->key.bsign_pub_key->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: { struct TALER_RsaPubHashP h_rsa; - TALER_rsa_pub_hash (denom_key->key.details.rsa_public_key, - &h_rsa); + TALER_rsa_pub_hash ( + denom_key->key.bsign_pub_key->details.rsa_public_key, + &h_rsa); if (GNUNET_OK != TALER_exchange_secmod_rsa_verify (&h_rsa, section_name, @@ -250,12 +251,13 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle *gh, } } break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct TALER_CsPubHashP h_cs; - TALER_cs_pub_hash (&denom_key->key.details.cs_public_key, - &h_cs); + TALER_cs_pub_hash ( + &denom_key->key.bsign_pub_key->details.cs_public_key, + &h_cs); if (GNUNET_OK != TALER_exchange_secmod_cs_verify (&h_cs, section_name, diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index ba4241dab..24b064476 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -308,7 +308,13 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh) struct TALER_ExchangeWithdrawValues alg_values[mh->rd->fresh_pks_len]; for (unsigned int i = 0; i<mh->rd->fresh_pks_len; i++) - alg_values[i] = mh->mbds[i].alg_value; + { + if (GNUNET_CRYPTO_BSA_RSA == + mh->rd->fresh_pks[i].key.bsign_pub_key->cipher) + alg_values[i] = *TALER_denom_ewv_rsa_singleton (); + else + alg_values[i] = mh->mbds[i].alg_value; + } if (GNUNET_OK != TALER_EXCHANGE_get_melt_data_ (&mh->rms, mh->rd, @@ -460,19 +466,18 @@ csr_cb (void *cls, &mh->rd->fresh_pks[i]; struct TALER_ExchangeWithdrawValues *wv = &mh->mbds[i].alg_value; - switch (fresh_pk->key.cipher) + switch (fresh_pk->key.bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_break (0); fail_mh (mh, TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR); return; - case TALER_DENOMINATION_RSA: - GNUNET_assert (TALER_DENOMINATION_RSA == wv->cipher); + case GNUNET_CRYPTO_BSA_RSA: break; - case TALER_DENOMINATION_CS: - GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher); - *wv = csrr->details.ok.alg_values[nks_off]; + case GNUNET_CRYPTO_BSA_CS: + TALER_denom_ewv_deep_copy (wv, + &csrr->details.ok.alg_values[nks_off]); nks_off++; break; } @@ -521,20 +526,19 @@ TALER_EXCHANGE_melt ( for (unsigned int i = 0; i<rd->fresh_pks_len; i++) { const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i]; - struct TALER_ExchangeWithdrawValues *wv = &mh->mbds[i].alg_value; - switch (fresh_pk->key.cipher) + switch (fresh_pk->key.bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_break (0); GNUNET_free (mh->mbds); GNUNET_free (mh); return NULL; - case TALER_DENOMINATION_RSA: - wv->cipher = TALER_DENOMINATION_RSA; + case GNUNET_CRYPTO_BSA_RSA: + TALER_denom_ewv_deep_copy (&mh->mbds[i].alg_value, + TALER_denom_ewv_rsa_singleton ()); break; - case TALER_DENOMINATION_CS: - wv->cipher = TALER_DENOMINATION_CS; + case GNUNET_CRYPTO_BSA_CS: nks[nks_off].pk = fresh_pk; nks[nks_off].cnc_num = nks_off; nks_off++; @@ -573,6 +577,8 @@ TALER_EXCHANGE_melt ( void TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh) { + for (unsigned int i = 0; i<mh->rd->fresh_pks_len; i++) + TALER_denom_ewv_free (&mh->mbds[i].alg_value); if (NULL != mh->job) { GNUNET_CURL_job_cancel (mh->job); diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c index cfd265f04..56499f381 100644 --- a/src/lib/exchange_api_recoup.c +++ b/src/lib/exchange_api_recoup.c @@ -245,7 +245,7 @@ TALER_EXCHANGE_recoup ( CURL *eh; char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32]; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle); TALER_planchet_setup_coin_priv (ps, @@ -273,22 +273,32 @@ TALER_EXCHANGE_recoup ( &ph->coin_sig), GNUNET_JSON_pack_data_auto ("coin_blind_key_secret", &bks)); - if (TALER_DENOMINATION_CS == denom_sig->cipher) + switch (denom_sig->unblinded_sig->cipher) { - struct TALER_CsNonce nonce; - - /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash() - it is not strictly clear that the nonce is needed. Best case would be - to find a way to include it more 'naturally' somehow, for example with - the variant union version of bks! */ - TALER_cs_withdraw_nonce_derive (ps, - &nonce); - GNUNET_assert ( - 0 == - json_object_set_new (recoup_obj, - "cs_nonce", - GNUNET_JSON_from_data_auto ( - &nonce))); + case GNUNET_CRYPTO_BSA_INVALID: + json_decref (recoup_obj); + GNUNET_break (0); + GNUNET_free (ph); + return NULL; + case GNUNET_CRYPTO_BSA_RSA: + break; + case GNUNET_CRYPTO_BSA_CS: + { + union GNUNET_CRYPTO_BlindSessionNonce nonce; + + /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash() + it is not strictly clear that the nonce is needed. Best case would be + to find a way to include it more 'naturally' somehow, for example with + the variant union version of bks! */ + TALER_cs_withdraw_nonce_derive (ps, + &nonce.cs_nonce); + GNUNET_assert ( + 0 == + json_object_set_new (recoup_obj, + "cs_nonce", + GNUNET_JSON_from_data_auto ( + &nonce))); + } } { diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c index 0bcd44dec..0c2e21cbf 100644 --- a/src/lib/exchange_api_recoup_refresh.c +++ b/src/lib/exchange_api_recoup_refresh.c @@ -235,7 +235,7 @@ TALER_EXCHANGE_recoup_refresh ( CURL *eh; char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32]; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; GNUNET_assert (NULL != recoup_cb); ph = GNUNET_new (struct TALER_EXCHANGE_RecoupRefreshHandle); @@ -271,23 +271,34 @@ TALER_EXCHANGE_recoup_refresh ( GNUNET_JSON_pack_data_auto ("coin_blind_key_secret", &bks)); - if (TALER_DENOMINATION_CS == denom_sig->cipher) + switch (denom_sig->unblinded_sig->cipher) { - struct TALER_CsNonce nonce; - - /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash() - it is not strictly clear that the nonce is needed. Best case would be - to find a way to include it more 'naturally' somehow, for example with - the variant union version of bks! */ - TALER_cs_refresh_nonce_derive (rms, - idx, - &nonce); - GNUNET_assert ( - 0 == - json_object_set_new (recoup_obj, - "cs_nonce", - GNUNET_JSON_from_data_auto ( - &nonce))); + case GNUNET_CRYPTO_BSA_INVALID: + json_decref (recoup_obj); + GNUNET_break (0); + GNUNET_free (ph); + return NULL; + case GNUNET_CRYPTO_BSA_RSA: + break; + case GNUNET_CRYPTO_BSA_CS: + { + union GNUNET_CRYPTO_BlindSessionNonce nonce; + + /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash() + it is not strictly clear that the nonce is needed. Best case would be + to find a way to include it more 'naturally' somehow, for example with + the variant union version of bks! */ + TALER_cs_refresh_nonce_derive (rms, + idx, + &nonce.cs_nonce); + GNUNET_assert ( + 0 == + json_object_set_new (recoup_obj, + "cs_nonce", + GNUNET_JSON_from_data_auto ( + &nonce))); + } + break; } { diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 0a6665b55..652581d8e 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -68,7 +68,7 @@ TALER_EXCHANGE_get_melt_data_ ( { struct TALER_Amount total; struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_CsNonce nonces[rd->fresh_pks_len]; + union GNUNET_CRYPTO_BlindSessionNonce nonces[rd->fresh_pks_len]; bool uses_cs = false; GNUNET_CRYPTO_eddsa_key_get_public (&rd->melt_priv.eddsa_priv, @@ -99,22 +99,31 @@ TALER_EXCHANGE_get_melt_data_ ( { struct FreshCoinData *fcd = &md->fcds[j]; - if (alg_values[j].cipher != rd->fresh_pks[j].key.cipher) + TALER_denom_pub_deep_copy (&fcd->fresh_pk, + &rd->fresh_pks[j].key); + GNUNET_assert (NULL != fcd->fresh_pk.bsign_pub_key); + if (alg_values[j].blinding_inputs->cipher != + fcd->fresh_pk.bsign_pub_key->cipher) { GNUNET_break (0); TALER_EXCHANGE_free_melt_data_ (md); return GNUNET_SYSERR; } - if (TALER_DENOMINATION_CS == alg_values[j].cipher) + switch (fcd->fresh_pk.bsign_pub_key->cipher) { + case GNUNET_CRYPTO_BSA_INVALID: + GNUNET_break (0); + TALER_EXCHANGE_free_melt_data_ (md); + return GNUNET_SYSERR; + case GNUNET_CRYPTO_BSA_RSA: + break; + case GNUNET_CRYPTO_BSA_CS: uses_cs = true; - TALER_cs_refresh_nonce_derive ( - rms, - j, - &nonces[j]); + TALER_cs_refresh_nonce_derive (rms, + j, + &nonces[j].cs_nonce); + break; } - TALER_denom_pub_deep_copy (&fcd->fresh_pk, - &rd->fresh_pks[j].key); if ( (0 > TALER_amount_add (&total, &total, @@ -170,7 +179,7 @@ TALER_EXCHANGE_get_melt_data_ ( struct TALER_CoinSpendPrivateKeyP *coin_priv = &fcd->coin_priv; struct TALER_PlanchetMasterSecretP *ps = &fcd->ps[i]; struct TALER_RefreshCoinData *rcd = &md->rcd[i][j]; - union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i]; + union GNUNET_CRYPTO_BlindingSecretP *bks = &fcd->bks[i]; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHashP c_hash; struct TALER_AgeCommitmentHash ach; @@ -205,13 +214,11 @@ TALER_EXCHANGE_get_melt_data_ ( pah = &ach; } - if (TALER_DENOMINATION_CS == alg_values[j].cipher) - pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonces[j]; - if (GNUNET_OK != TALER_planchet_prepare (&fcd->fresh_pk, &alg_values[j], bks, + &nonces[j], coin_priv, pah, &c_hash, diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h index 0cb80f17e..f596e1e90 100644 --- a/src/lib/exchange_api_refresh_common.h +++ b/src/lib/exchange_api_refresh_common.h @@ -109,7 +109,7 @@ struct FreshCoinData * Blinding key secrets for the coins, depending on the * cut-and-choose. */ - union TALER_DenominationBlindingKeyP bks[TALER_CNC_KAPPA]; + union GNUNET_CRYPTO_BlindingSecretP bks[TALER_CNC_KAPPA]; }; diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index 220682992..7eadab228 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -138,23 +138,19 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, GNUNET_JSON_spec_end () }; struct TALER_FreshCoin coin; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; const struct TALER_AgeCommitmentHash *pah = NULL; rci->ps = fcd->ps[rrh->noreveal_index]; rci->bks = fcd->bks[rrh->noreveal_index]; rci->age_commitment_proof = NULL; - pk = &fcd->fresh_pk; jsonai = json_array_get (jsona, i); - GNUNET_assert (NULL != jsonai); - if (NULL != rrh->md.melted_coin.age_commitment_proof) { - rci->age_commitment_proof = - fcd->age_commitment_proofs[rrh->noreveal_index]; - + rci->age_commitment_proof + = fcd->age_commitment_proofs[rrh->noreveal_index]; TALER_age_commitment_hash (&rci->age_commitment_proof->commitment, &rci->h_age_commitment); pah = &rci->h_age_commitment; @@ -360,7 +356,8 @@ TALER_EXCHANGE_refreshes_reveal ( const struct TALER_RefreshCoinData *rcd = &md.rcd[noreveal_index][i]; struct TALER_DenominationHashP denom_hash; - if (TALER_DENOMINATION_CS == md.fcds[i].fresh_pk.cipher) + if (GNUNET_CRYPTO_BSA_CS == + md.fcds[i].fresh_pk.bsign_pub_key->cipher) send_rms = true; TALER_denom_pub_hash (&md.fcds[i].fresh_pk, &denom_hash); @@ -419,6 +416,7 @@ TALER_EXCHANGE_refreshes_reveal ( for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++) { enum GNUNET_GenericReturnValue ret; + ret = json_array_append_new ( old_age_commitment, GNUNET_JSON_from_data_auto ( @@ -469,9 +467,11 @@ TALER_EXCHANGE_refreshes_reveal ( rrh->reveal_cb_cls = reveal_cb_cls; rrh->md = md; rrh->alg_values - = GNUNET_memdup (alg_values, - md.num_fresh_coins - * sizeof (struct TALER_ExchangeWithdrawValues)); + = GNUNET_new_array (md.num_fresh_coins, + struct TALER_ExchangeWithdrawValues); + for (unsigned int i = 0; i<md.num_fresh_coins; i++) + TALER_denom_ewv_deep_copy (&rrh->alg_values[i], + &alg_values[i]); rrh->url = TALER_url_join (url, arg_str, NULL); @@ -520,6 +520,8 @@ TALER_EXCHANGE_refreshes_reveal_cancel ( GNUNET_CURL_job_cancel (rrh->job); rrh->job = NULL; } + for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++) + TALER_denom_ewv_free (&rrh->alg_values[i]); GNUNET_free (rrh->alg_values); GNUNET_free (rrh->url); TALER_curl_easy_post_finished (&rrh->ctx); diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index dd6cf6733..f66844515 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -234,6 +234,7 @@ qconv_denom_pub (void *cls, unsigned int scratch_length) { const struct TALER_DenominationPublicKey *denom_pub = data; + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp = denom_pub->bsign_pub_key; size_t tlen; size_t len; uint32_t be[2]; @@ -245,17 +246,17 @@ qconv_denom_pub (void *cls, GNUNET_assert (1 == param_length); GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); - be[0] = htonl ((uint32_t) denom_pub->cipher); + be[0] = htonl ((uint32_t) bsp->cipher); be[1] = htonl (denom_pub->age_mask.bits); - switch (denom_pub->cipher) + switch (bsp->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: tlen = GNUNET_CRYPTO_rsa_public_key_encode ( - denom_pub->details.rsa_public_key, + bsp->details.rsa_public_key, &tbuf); break; - case TALER_DENOMINATION_CS: - tlen = sizeof (denom_pub->details.cs_public_key); + case GNUNET_CRYPTO_BSA_CS: + tlen = sizeof (bsp->details.cs_public_key); break; default: GNUNET_assert (0); @@ -265,17 +266,17 @@ qconv_denom_pub (void *cls, GNUNET_memcpy (buf, be, sizeof (be)); - switch (denom_pub->cipher) + switch (bsp->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: GNUNET_memcpy (&buf[sizeof (be)], tbuf, tlen); GNUNET_free (tbuf); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (&buf[sizeof (be)], - &denom_pub->details.cs_public_key, + &bsp->details.cs_public_key, tlen); break; default: @@ -330,6 +331,7 @@ qconv_denom_sig (void *cls, unsigned int scratch_length) { const struct TALER_DenominationSignature *denom_sig = data; + const struct GNUNET_CRYPTO_UnblindedSignature *ubs = denom_sig->unblinded_sig; size_t tlen; size_t len; uint32_t be[2]; @@ -341,17 +343,17 @@ qconv_denom_sig (void *cls, GNUNET_assert (1 == param_length); GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); - be[0] = htonl ((uint32_t) denom_sig->cipher); + be[0] = htonl ((uint32_t) ubs->cipher); be[1] = htonl (0x00); /* magic marker: unblinded */ - switch (denom_sig->cipher) + switch (ubs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: tlen = GNUNET_CRYPTO_rsa_signature_encode ( - denom_sig->details.rsa_signature, + ubs->details.rsa_signature, &tbuf); break; - case TALER_DENOMINATION_CS: - tlen = sizeof (denom_sig->details.cs_signature); + case GNUNET_CRYPTO_BSA_CS: + tlen = sizeof (ubs->details.cs_signature); break; default: GNUNET_assert (0); @@ -361,17 +363,17 @@ qconv_denom_sig (void *cls, GNUNET_memcpy (buf, &be, sizeof (be)); - switch (denom_sig->cipher) + switch (ubs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: GNUNET_memcpy (&buf[sizeof (be)], tbuf, tlen); GNUNET_free (tbuf); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (&buf[sizeof (be)], - &denom_sig->details.cs_signature, + &ubs->details.cs_signature, tlen); break; default: @@ -426,6 +428,7 @@ qconv_blinded_denom_sig (void *cls, unsigned int scratch_length) { const struct TALER_BlindedDenominationSignature *denom_sig = data; + const struct GNUNET_CRYPTO_BlindedSignature *bs = denom_sig->blinded_sig; size_t tlen; size_t len; uint32_t be[2]; @@ -437,17 +440,17 @@ qconv_blinded_denom_sig (void *cls, GNUNET_assert (1 == param_length); GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); - be[0] = htonl ((uint32_t) denom_sig->cipher); + be[0] = htonl ((uint32_t) bs->cipher); be[1] = htonl (0x01); /* magic marker: blinded */ - switch (denom_sig->cipher) + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: tlen = GNUNET_CRYPTO_rsa_signature_encode ( - denom_sig->details.blinded_rsa_signature, + bs->details.blinded_rsa_signature, &tbuf); break; - case TALER_DENOMINATION_CS: - tlen = sizeof (denom_sig->details.blinded_cs_answer); + case GNUNET_CRYPTO_BSA_CS: + tlen = sizeof (bs->details.blinded_cs_answer); break; default: GNUNET_assert (0); @@ -457,17 +460,17 @@ qconv_blinded_denom_sig (void *cls, GNUNET_memcpy (buf, &be, sizeof (be)); - switch (denom_sig->cipher) + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: GNUNET_memcpy (&buf[sizeof (be)], tbuf, tlen); GNUNET_free (tbuf); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (&buf[sizeof (be)], - &denom_sig->details.blinded_cs_answer, + &bs->details.blinded_cs_answer, tlen); break; default: @@ -522,6 +525,7 @@ qconv_blinded_planchet (void *cls, unsigned int scratch_length) { const struct TALER_BlindedPlanchet *bp = data; + const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message; size_t tlen; size_t len; uint32_t be[2]; @@ -532,15 +536,15 @@ qconv_blinded_planchet (void *cls, GNUNET_assert (1 == param_length); GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); - be[0] = htonl ((uint32_t) bp->cipher); + be[0] = htonl ((uint32_t) bm->cipher); be[1] = htonl (0x0100); /* magic marker: blinded */ - switch (bp->cipher) + switch (bm->cipher) { - case TALER_DENOMINATION_RSA: - tlen = bp->details.rsa_blinded_planchet.blinded_msg_size; + case GNUNET_CRYPTO_BSA_RSA: + tlen = bm->details.rsa_blinded_message.blinded_msg_size; break; - case TALER_DENOMINATION_CS: - tlen = sizeof (bp->details.cs_blinded_planchet); + case GNUNET_CRYPTO_BSA_CS: + tlen = sizeof (bm->details.cs_blinded_message); break; default: GNUNET_assert (0); @@ -550,16 +554,16 @@ qconv_blinded_planchet (void *cls, GNUNET_memcpy (buf, &be, sizeof (be)); - switch (bp->cipher) + switch (bm->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: GNUNET_memcpy (&buf[sizeof (be)], - bp->details.rsa_blinded_planchet.blinded_msg, + bm->details.rsa_blinded_message.blinded_msg, tlen); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (&buf[sizeof (be)], - &bp->details.cs_blinded_planchet, + &bm->details.cs_blinded_message, tlen); break; default: @@ -613,6 +617,8 @@ qconv_exchange_withdraw_values (void *cls, unsigned int scratch_length) { const struct TALER_ExchangeWithdrawValues *alg_values = data; + const struct GNUNET_CRYPTO_BlindingInputValues *bi = + alg_values->blinding_inputs; size_t tlen; size_t len; uint32_t be[2]; @@ -623,15 +629,15 @@ qconv_exchange_withdraw_values (void *cls, GNUNET_assert (1 == param_length); GNUNET_assert (scratch_length > 0); GNUNET_break (NULL == cls); - be[0] = htonl ((uint32_t) alg_values->cipher); + be[0] = htonl ((uint32_t) bi->cipher); be[1] = htonl (0x010000); /* magic marker: EWV */ - switch (alg_values->cipher) + switch (bi->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: tlen = 0; break; - case TALER_DENOMINATION_CS: - tlen = sizeof (struct TALER_DenominationCSPublicRPairP); + case GNUNET_CRYPTO_BSA_CS: + tlen = sizeof (struct GNUNET_CRYPTO_CSPublicRPairP); break; default: GNUNET_assert (0); @@ -641,13 +647,13 @@ qconv_exchange_withdraw_values (void *cls, GNUNET_memcpy (buf, &be, sizeof (be)); - switch (alg_values->cipher) + switch (bi->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (&buf[sizeof (be)], - &alg_values->details.cs_values, + &bi->details.cs_values, tlen); break; default: @@ -840,14 +846,14 @@ qconv_array ( same_sized = (0 != meta->same_size); #define RETURN_UNLESS(cond) \ - do { \ - if (! (cond)) \ - { \ - GNUNET_break ((cond)); \ - noerror = false; \ - goto DONE; \ - } \ - } while (0) + do { \ + if (! (cond)) \ + { \ + GNUNET_break ((cond)); \ + noerror = false; \ + goto DONE; \ + } \ + } while (0) /* Calculate sizes and check bounds */ { @@ -885,16 +891,19 @@ qconv_array ( for (size_t i = 0; i<num; i++) { - switch (denom_sigs[i].cipher) + const struct GNUNET_CRYPTO_BlindedSignature *bs = + denom_sigs[i].blinded_sig; + + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: len = GNUNET_CRYPTO_rsa_signature_encode ( - denom_sigs[i].details.blinded_rsa_signature, + bs->details.blinded_rsa_signature, &buffers[i]); RETURN_UNLESS (len != 0); break; - case TALER_DENOMINATION_CS: - len = sizeof (denom_sigs[i].details.blinded_cs_answer); + case GNUNET_CRYPTO_BSA_CS: + len = sizeof (bs->details.blinded_cs_answer); break; default: GNUNET_assert (0); @@ -978,9 +987,11 @@ qconv_array ( case TALER_PQ_array_of_blinded_denom_sig: { const struct TALER_BlindedDenominationSignature *denom_sigs = data; + const struct GNUNET_CRYPTO_BlindedSignature *bs = + denom_sigs[i].blinded_sig; uint32_t be[2]; - be[0] = htonl ((uint32_t) denom_sigs[i].cipher); + be[0] = htonl ((uint32_t) bs->cipher); be[1] = htonl (0x01); /* magic margker: blinded */ GNUNET_memcpy (out, &be, @@ -988,18 +999,18 @@ qconv_array ( out += sizeof(be); sz -= sizeof(be); - switch (denom_sigs[i].cipher) + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: /* For RSA, 'same_sized' must have been false */ GNUNET_assert (NULL != buffers); GNUNET_memcpy (out, buffers[i], sz); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_memcpy (out, - &denom_sigs[i].details.blinded_cs_answer, + &bs->details.blinded_cs_answer, sz); break; default: diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 95850bcc0..6f4338666 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER 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 @@ -425,6 +425,7 @@ extract_denom_pub (void *cls, void *dst) { struct TALER_DenominationPublicKey *pk = dst; + struct GNUNET_CRYPTO_BlindSignPublicKey *bpk; size_t len; const char *res; int fnum; @@ -462,33 +463,47 @@ extract_denom_pub (void *cls, sizeof (be)); res += sizeof (be); len -= sizeof (be); - pk->cipher = ntohl (be[0]); + bpk = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bpk->cipher = ntohl (be[0]); + bpk->rc = 1; pk->age_mask.bits = ntohl (be[1]); - switch (pk->cipher) + switch (bpk->cipher) { - case TALER_DENOMINATION_RSA: - pk->details.rsa_public_key + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + bpk->details.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (res, len); - if (NULL == pk->details.rsa_public_key) + if (NULL == bpk->details.rsa_public_key) { GNUNET_break (0); + GNUNET_free (bpk); return GNUNET_SYSERR; } + pk->bsign_pub_key = bpk; + GNUNET_CRYPTO_hash (res, + len, + &bpk->pub_key_hash); return GNUNET_OK; - case TALER_DENOMINATION_CS: - if (sizeof (pk->details.cs_public_key) != len) + case GNUNET_CRYPTO_BSA_CS: + if (sizeof (bpk->details.cs_public_key) != len) { GNUNET_break (0); + GNUNET_free (bpk); return GNUNET_SYSERR; } - GNUNET_memcpy (&pk->details.cs_public_key, + GNUNET_memcpy (&bpk->details.cs_public_key, res, len); + pk->bsign_pub_key = bpk; + GNUNET_CRYPTO_hash (res, + len, + &bpk->pub_key_hash); return GNUNET_OK; - default: - GNUNET_break (0); } + GNUNET_break (0); + GNUNET_free (bpk); return GNUNET_SYSERR; } @@ -548,6 +563,7 @@ extract_denom_sig (void *cls, void *dst) { struct TALER_DenominationSignature *sig = dst; + struct GNUNET_CRYPTO_UnblindedSignature *ubs; size_t len; const char *res; int fnum; @@ -590,32 +606,40 @@ extract_denom_sig (void *cls, } res += sizeof (be); len -= sizeof (be); - sig->cipher = ntohl (be[0]); - switch (sig->cipher) + ubs = GNUNET_new (struct GNUNET_CRYPTO_UnblindedSignature); + ubs->rc = 1; + ubs->cipher = ntohl (be[0]); + switch (ubs->cipher) { - case TALER_DENOMINATION_RSA: - sig->details.rsa_signature + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + ubs->details.rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (res, len); - if (NULL == sig->details.rsa_signature) + if (NULL == ubs->details.rsa_signature) { GNUNET_break (0); + GNUNET_free (ubs); return GNUNET_SYSERR; } + sig->unblinded_sig = ubs; return GNUNET_OK; - case TALER_DENOMINATION_CS: - if (sizeof (sig->details.cs_signature) != len) + case GNUNET_CRYPTO_BSA_CS: + if (sizeof (ubs->details.cs_signature) != len) { GNUNET_break (0); + GNUNET_free (ubs); return GNUNET_SYSERR; } - GNUNET_memcpy (&sig->details.cs_signature, + GNUNET_memcpy (&ubs->details.cs_signature, res, len); + sig->unblinded_sig = ubs; return GNUNET_OK; - default: - GNUNET_break (0); } + GNUNET_break (0); + GNUNET_free (ubs); return GNUNET_SYSERR; } @@ -675,6 +699,7 @@ extract_blinded_denom_sig (void *cls, void *dst) { struct TALER_BlindedDenominationSignature *sig = dst; + struct GNUNET_CRYPTO_BlindedSignature *bs; size_t len; const char *res; int fnum; @@ -717,32 +742,40 @@ extract_blinded_denom_sig (void *cls, } res += sizeof (be); len -= sizeof (be); - sig->cipher = ntohl (be[0]); - switch (sig->cipher) + bs = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + bs->rc = 1; + bs->cipher = ntohl (be[0]); + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: - sig->details.blinded_rsa_signature + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + bs->details.blinded_rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (res, len); - if (NULL == sig->details.blinded_rsa_signature) + if (NULL == bs->details.blinded_rsa_signature) { GNUNET_break (0); + GNUNET_free (bs); return GNUNET_SYSERR; } + sig->blinded_sig = bs; return GNUNET_OK; - case TALER_DENOMINATION_CS: - if (sizeof (sig->details.blinded_cs_answer) != len) + case GNUNET_CRYPTO_BSA_CS: + if (sizeof (bs->details.blinded_cs_answer) != len) { GNUNET_break (0); + GNUNET_free (bs); return GNUNET_SYSERR; } - GNUNET_memcpy (&sig->details.blinded_cs_answer, + GNUNET_memcpy (&bs->details.blinded_cs_answer, res, len); + sig->blinded_sig = bs; return GNUNET_OK; - default: - GNUNET_break (0); } + GNUNET_break (0); + GNUNET_free (bs); return GNUNET_SYSERR; } @@ -803,6 +836,7 @@ extract_blinded_planchet (void *cls, void *dst) { struct TALER_BlindedPlanchet *bp = dst; + struct GNUNET_CRYPTO_BlindedMessage *bm; size_t len; const char *res; int fnum; @@ -845,29 +879,36 @@ extract_blinded_planchet (void *cls, } res += sizeof (be); len -= sizeof (be); - bp->cipher = ntohl (be[0]); - switch (bp->cipher) + bm = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + bm->rc = 1; + bm->cipher = ntohl (be[0]); + switch (bm->cipher) { - case TALER_DENOMINATION_RSA: - bp->details.rsa_blinded_planchet.blinded_msg_size + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + bm->details.rsa_blinded_message.blinded_msg_size = len; - bp->details.rsa_blinded_planchet.blinded_msg + bm->details.rsa_blinded_message.blinded_msg = GNUNET_memdup (res, len); + bp->blinded_message = bm; return GNUNET_OK; - case TALER_DENOMINATION_CS: - if (sizeof (bp->details.cs_blinded_planchet) != len) + case GNUNET_CRYPTO_BSA_CS: + if (sizeof (bm->details.cs_blinded_message) != len) { GNUNET_break (0); + GNUNET_free (bm); return GNUNET_SYSERR; } - GNUNET_memcpy (&bp->details.cs_blinded_planchet, + GNUNET_memcpy (&bm->details.cs_blinded_message, res, len); + bp->blinded_message = bm; return GNUNET_OK; - default: - GNUNET_break (0); } + GNUNET_break (0); + GNUNET_free (bm); return GNUNET_SYSERR; } @@ -928,6 +969,7 @@ extract_exchange_withdraw_values (void *cls, void *dst) { struct TALER_ExchangeWithdrawValues *alg_values = dst; + struct GNUNET_CRYPTO_BlindingInputValues *bi; size_t len; const char *res; int fnum; @@ -970,29 +1012,37 @@ extract_exchange_withdraw_values (void *cls, } res += sizeof (be); len -= sizeof (be); - alg_values->cipher = ntohl (be[0]); - switch (alg_values->cipher) + bi = GNUNET_new (struct GNUNET_CRYPTO_BlindingInputValues); + bi->rc = 1; + bi->cipher = ntohl (be[0]); + switch (bi->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: if (0 != len) { GNUNET_break (0); + GNUNET_free (bi); return GNUNET_SYSERR; } + alg_values->blinding_inputs = bi; return GNUNET_OK; - case TALER_DENOMINATION_CS: - if (sizeof (struct TALER_DenominationCSPublicRPairP) != len) + case GNUNET_CRYPTO_BSA_CS: + if (sizeof (bi->details.cs_values) != len) { GNUNET_break (0); + GNUNET_free (bi); return GNUNET_SYSERR; } - GNUNET_memcpy (&alg_values->details.cs_values, + GNUNET_memcpy (&bi->details.cs_values, res, len); + alg_values->blinding_inputs = bi; return GNUNET_OK; - default: - GNUNET_break (0); } + GNUNET_break (0); + GNUNET_free (bi); return GNUNET_SYSERR; } @@ -1018,29 +1068,44 @@ TALER_PQ_result_spec_exchange_withdraw_values ( */ struct ArrayResultCls { - /* Oid of the expected type, must match the oid in the header of the PQResult struct */ + /** + * Oid of the expected type, must match the oid in the header of the PQResult struct + */ Oid oid; - /* Target type */ + /** + * Target type + */ enum TALER_PQ_ArrayType typ; - /* If not 0, defines the expected size of each entry */ + /** + * If not 0, defines the expected size of each entry + */ size_t same_size; - /* Out-pointer to write the number of elements in the array */ + /** + * Out-pointer to write the number of elements in the array + */ size_t *num; - /* Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0, - * allocate and put the array of @a num sizes here. NULL otherwise */ + /** + * Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0, + * allocate and put the array of @a num sizes here. NULL otherwise + */ size_t **sizes; - /* DB_connection, needed for OID-lookup for composite types */ + /** + * DB_connection, needed for OID-lookup for composite types + */ const struct GNUNET_PQ_Context *db; - /* Currency information for amount composites */ + /** + * Currency information for amount composites + */ char currency[TALER_CURRENCY_LEN]; }; + /** * Extract data from a Postgres database @a result as array of a specific type * from row @a row. The type information and optionally additional @@ -1076,13 +1141,13 @@ extract_array_generic ( *((void **) dst) = NULL; #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto FAIL; \ - } \ - } while (0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto FAIL; \ + } \ + } while (0) col_num = PQfnumber (result, fname); FAIL_IF (0 > col_num); @@ -1125,7 +1190,8 @@ extract_array_generic ( if (NULL != dst_size) *dst_size = sizeof(struct TALER_Amount) * (header.dim); - amounts = GNUNET_new_array (header.dim, struct TALER_Amount); + amounts = GNUNET_new_array (header.dim, + struct TALER_Amount); *((void **) dst) = amounts; for (uint32_t i = 0; i < header.dim; i++) @@ -1162,7 +1228,8 @@ extract_array_generic ( case TALER_PQ_array_of_denom_hash: if (NULL != dst_size) *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim); - out = GNUNET_new_array (header.dim, struct TALER_DenominationHashP); + out = GNUNET_new_array (header.dim, + struct TALER_DenominationHashP); *((void **) dst) = out; for (uint32_t i = 0; i < header.dim; i++) { @@ -1185,7 +1252,8 @@ extract_array_generic ( case TALER_PQ_array_of_blinded_coin_hash: if (NULL != dst_size) *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim); - out = GNUNET_new_array (header.dim, struct TALER_BlindedCoinHashP); + out = GNUNET_new_array (header.dim, + struct TALER_BlindedCoinHashP); *((void **) dst) = out; for (uint32_t i = 0; i < header.dim; i++) { @@ -1223,6 +1291,7 @@ extract_array_generic ( for (uint32_t i = 0; i < header.dim; i++) { struct TALER_BlindedDenominationSignature *denom_sig = &denom_sigs[i]; + struct GNUNET_CRYPTO_BlindedSignature *bs; uint32_t be[2]; uint32_t val; size_t sz; @@ -1241,28 +1310,36 @@ extract_array_generic ( in += sizeof(be); sz -= sizeof(be); - - denom_sig->cipher = ntohl (be[0]); - switch (denom_sig->cipher) + bs = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + bs->cipher = ntohl (be[0]); + bs->rc = 1; + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: - denom_sig->details.blinded_rsa_signature = - GNUNET_CRYPTO_rsa_signature_decode (in, - sz); - FAIL_IF (NULL == denom_sig->details.blinded_rsa_signature); + case GNUNET_CRYPTO_BSA_RSA: + bs->details.blinded_rsa_signature + = GNUNET_CRYPTO_rsa_signature_decode (in, + sz); + if (NULL == bs->details.blinded_rsa_signature) + { + GNUNET_free (bs); + FAIL_IF (true); + } break; - - case TALER_DENOMINATION_CS: - FAIL_IF (sizeof(denom_sig->details.blinded_cs_answer) != sz); - GNUNET_memcpy (&denom_sig->details.blinded_cs_answer, + case GNUNET_CRYPTO_BSA_CS: + if (sizeof(bs->details.blinded_cs_answer) != sz) + { + GNUNET_free (bs); + FAIL_IF (true); + } + GNUNET_memcpy (&bs->details.blinded_cs_answer, in, sz); break; - default: + GNUNET_free (bs); FAIL_IF (true); } - + denom_sig->blinded_sig = bs; in += sz; } return GNUNET_OK; @@ -1271,12 +1348,10 @@ extract_array_generic ( FAIL_IF (true); } } - FAIL: GNUNET_free (*(void **) dst); return GNUNET_SYSERR; - #undef FAIL_IF - +#undef FAIL_IF } @@ -1287,10 +1362,11 @@ static void array_cleanup (void *cls, void *rd) { - struct ArrayResultCls *info = cls; void **dst = rd; + /* FIXME-Oec: this does not properly clean up + denomination signatures! */ if ((0 == info->same_size) && (NULL != info->sizes)) GNUNET_free (*(info->sizes)); diff --git a/src/templating/Makefile.am b/src/templating/Makefile.am index f960bdcca..f74322982 100644 --- a/src/templating/Makefile.am +++ b/src/templating/Makefile.am @@ -32,9 +32,10 @@ libtalertemplating_la_SOURCES = \ libtalertemplating_la_LIBADD = \ $(top_builddir)/src/mhd/libtalermhd.la \ $(top_builddir)/src/util/libtalerutil.la \ - -ljansson \ -lmicrohttpd \ + -lgnunetjson \ -lgnunetutil \ + -ljansson \ $(XLIB) libtalertemplating_la_LDFLAGS = \ -version-info 0:0:0 \ diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index a26d8deb1..18fe2a49b 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -548,6 +548,7 @@ test_kyc_api_LDADD = \ EXTRA_DIST = \ $(bin_SCRIPTS) \ + valgrind.h \ coins-cs.conf \ coins-rsa.conf \ test_auditor_api-cs.conf \ diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh index 8b3911fd5..13b715503 100755 --- a/src/testing/taler-unified-setup.sh +++ b/src/testing/taler-unified-setup.sh @@ -67,6 +67,7 @@ START_AUDITOR=0 START_BACKUP=0 START_EXCHANGE=0 START_FAKEBANK=0 +START_CHALLENGER=0 START_AGGREGATOR=0 START_MERCHANT=0 START_NEXUS=0 @@ -81,7 +82,7 @@ LOGLEVEL="DEBUG" DEFAULT_SLEEP="0.2" # Parse command-line options -while getopts ':abc:d:efghL:mnr:stu:vwW' OPTION; do +while getopts ':abc:d:efghkL:mnr:stu:vwW' OPTION; do case "$OPTION" in a) START_AUDITOR="1" @@ -130,6 +131,9 @@ while getopts ':abc:d:efghL:mnr:stu:vwW' OPTION; do g) START_AGGREGATOR="1" ;; + k) + START_CHALLENGER="1" + ;; L) LOGLEVEL="$OPTARG" ;; @@ -189,6 +193,13 @@ then echo " FOUND" fi +if [ "1" = "$START_CHALLENGER" ] +then + echo -n "Testing for Taler challenger" + challenger-httpd -h > /dev/null || exit_skip " challenger-httpd required" + echo " FOUND" +fi + if [ "1" = "$START_BACKUP" ] then echo -n "Testing for sync-httpd" @@ -227,6 +238,7 @@ register_bank_account() { MAYBE_IBAN="${4:-}" if test -n "$MAYBE_IBAN"; then + # shellcheck disable=SC2001 ENAME=$(echo "$3" | sed -e "s/ /+/g") # Note: this assumes that $3 has no spaces. Should probably escape in the future.. PAYTO="payto://iban/SANDBOXX/${MAYBE_IBAN}?receiver-name=$ENAME" @@ -304,7 +316,7 @@ then exit_skip "Failed to launch services (bank)" fi echo "OK" - echo -n "Set admin password..." + echo -n "Set admin password..." AUSER="admin" APASS="secret" libeufin-bank \ @@ -479,12 +491,56 @@ if [ "1" = "$START_BACKUP" ] then echo -n "Starting sync ..." SYNC_PORT=$(taler-config -c "$CONF" -s SYNC -o PORT) - SYNC_URL="http://localhost:${SYNC_PORT}/" + SERVE=$(taler-config -c "$CONF" -s SYNC -o SERVE) + if [ "${SERVE}" = "unix" ] + then + SYNC_URL=$(taler-config -c "$CONF" -s SYNC -o BASE_URL) + else + SYNC_URL="http://localhost:${SYNC_PORT}/" + fi sync-dbinit -c "$CONF" --reset $USE_VALGRIND sync-httpd -c "$CONF" -L "$LOGLEVEL" 2> sync-httpd.log & echo " DONE" fi +if [ "1" = "$START_CHALLENGER" ] +then + echo -n "Starting challenger ..." + CHALLENGER_PORT=$(challenger-config -c "$CONF" -s CHALLENGER -o PORT) + SERVE=$(taler-config -c "$CONF" -s CHALLENGER -o SERVE) + if [ "${SERVE}" = "unix" ] + then + CHALLENGER_URL=$(taler-config -c "$CONF" -s CHALLENGER -o BASE_URL) + else + CHALLENGER_URL="http://localhost:${CHALLENGER_PORT}/" + fi + challenger-dbinit -c "$CONF" --reset + $USE_VALGRIND challenger-httpd -c "$CONF" -L "$LOGLEVEL" 2> challenger-httpd.log & + echo " DONE" + for SECTION in $(taler-config -c "$CONF" -S | grep kyc-provider) + do + LOGIC=$(taler-config -c "$CONF" -s "$SECTION" -o "LOGIC") + if [ "${LOGIC}" = "oauth2" ] + then + INFO=$(taler-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_INFO_URL") + if [ "${CHALLENGER_URL}info" = "$INFO" ] + then + echo -n "Enabling Challenger client for $SECTION" + CLIENT_SECRET=$(taler-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_CLIENT_SECRET") + RFC_8959_PREFIX="secret-token:" + if ! echo "${CLIENT_SECRET}" | grep ^${RFC_8959_PREFIX} > /dev/null + then + exit_fail "Client secret does not begin with '${RFC_8959_PREFIX}'" + fi + REDIRECT_URI="${EXCHANGE_URL}kyc-proof/kyc-provider-example-challeger" + CLIENT_ID=$(challenger-admin --add="${CLIENT_SECRET}" --quiet "${REDIRECT_URI}") + taler-config -c "$CONF" -s "$SECTION" -o KYC_OAUTH2_CLIENT_ID -V "$CLIENT_ID" + echo " DONE" + fi + fi + done +fi + if [ "1" = "$START_AUDITOR" ] then @@ -512,6 +568,7 @@ echo -n "Waiting for Taler services ..." E_DONE=0 M_DONE=0 S_DONE=0 +K_DONE=0 A_DONE=0 for n in $(seq 1 20) do @@ -550,6 +607,17 @@ do -O /dev/null >/dev/null || continue S_DONE=1 fi + if [ "0" = "$K_DONE" ] && [ "1" = "$START_CHALLENGER" ] + then + echo -n "K" + wget \ + --tries=1 \ + --timeout=1 \ + "${CHALLENGER_URL}config" \ + -o /dev/null \ + -O /dev/null >/dev/null || continue + K_DONE=1 + fi if [ "0" = "$A_DONE" ] && [ "1" = "$START_AUDITOR" ] then echo -n "A" diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index b3ea88113..4ae47aff2 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -186,7 +186,12 @@ run (void *cls, GNUNET_TIME_UNIT_ZERO, "EUR:5", MHD_HTTP_OK), - TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay", + TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-1", + "deposit-simple", + MHD_HTTP_OK), + TALER_TESTING_cmd_sleep ("sleep-before-deposit-replay", + 1), + TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-2", "deposit-simple", MHD_HTTP_OK), /* This creates a conflict, as we have the same coin public key (reuse!), @@ -405,6 +410,14 @@ run (void *cls, TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age", "deposit-simple-age", MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age-1", + "deposit-simple-age", + MHD_HTTP_OK), + TALER_TESTING_cmd_sleep ("sleep-before-age-deposit-replay", + 1), + TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay-age-2", + "deposit-simple-age", + MHD_HTTP_OK), TALER_TESTING_cmd_end () }; diff --git a/src/testing/test_exchange_api.conf b/src/testing/test_exchange_api.conf index 1fc87230e..0d69773d5 100644 --- a/src/testing/test_exchange_api.conf +++ b/src/testing/test_exchange_api.conf @@ -92,7 +92,7 @@ KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me KYC_OAUTH2_CLIENT_ID = taler-exchange KYC_OAUTH2_CLIENT_SECRET = exchange-secret KYC_OAUTH2_POST_URL = http://example.com/ -KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"full_name":"{{last_name}}, {{first_name}}"}" +KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh [kyc-legitimization-close] OPERATION_TYPE = CLOSE diff --git a/src/testing/test_exchange_api_age_restriction.conf b/src/testing/test_exchange_api_age_restriction.conf index cd60781d4..a14d39989 100644 --- a/src/testing/test_exchange_api_age_restriction.conf +++ b/src/testing/test_exchange_api_age_restriction.conf @@ -78,7 +78,7 @@ KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me KYC_OAUTH2_CLIENT_ID = taler-exchange KYC_OAUTH2_CLIENT_SECRET = exchange-secret KYC_OAUTH2_POST_URL = http://example.com/ -KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"full_name":"{{last_name}}, {{first_name}}","birthdate":"{{birthdate}}"}" +KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh [kyc-legitimization-balance-high] OPERATION_TYPE = BALANCE diff --git a/src/testing/test_kyc_api.conf b/src/testing/test_kyc_api.conf index 7a212623a..b6bfdb055 100644 --- a/src/testing/test_kyc_api.conf +++ b/src/testing/test_kyc_api.conf @@ -15,7 +15,8 @@ KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me KYC_OAUTH2_CLIENT_ID = taler-exchange KYC_OAUTH2_CLIENT_SECRET = exchange-secret KYC_OAUTH2_POST_URL = http://example.com/ -KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"full_name":"{{last_name}}, {{first_name}}"}" +KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh +# "{"full_name":"{{last_name}}, {{first_name}}"}" [kyc-legitimization-balance-high] OPERATION_TYPE = BALANCE diff --git a/src/testing/testing_api_cmd_batch_withdraw.c b/src/testing/testing_api_cmd_batch_withdraw.c index f0b9dcad8..b455fc062 100644 --- a/src/testing/testing_api_cmd_batch_withdraw.c +++ b/src/testing/testing_api_cmd_batch_withdraw.c @@ -59,7 +59,7 @@ struct CoinState /** * Blinding key used during the operation. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Values contributed from the exchange during the diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 61074afa7..a80b44868 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -313,6 +313,22 @@ deposit_run (void *cls, return; } ds->is = is; + if (! GNUNET_TIME_absolute_is_zero (ds->refund_deadline.abs_time)) + { + struct GNUNET_TIME_Relative refund_deadline; + + refund_deadline + = GNUNET_TIME_absolute_get_remaining (ds->refund_deadline.abs_time); + ds->wire_deadline + = GNUNET_TIME_relative_to_timestamp ( + GNUNET_TIME_relative_multiply (refund_deadline, + 2)); + } + else + { + ds->refund_deadline = ds->wallet_timestamp; + ds->wire_deadline = GNUNET_TIME_timestamp_get (); + } if (NULL != ds->deposit_reference) { /* We're copying another deposit operation, initialize here. */ @@ -335,6 +351,7 @@ deposit_run (void *cls, ds->contract_terms = json_incref (ods->contract_terms); ds->wallet_timestamp = ods->wallet_timestamp; ds->refund_deadline = ods->refund_deadline; + ds->wire_deadline = ods->wire_deadline; ds->amount = ods->amount; ds->merchant_priv = ods->merchant_priv; ds->command_initialized = GNUNET_YES; @@ -415,23 +432,6 @@ deposit_run (void *cls, GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, &coin_pub.eddsa_pub); - if (! GNUNET_TIME_absolute_is_zero (ds->refund_deadline.abs_time)) - { - struct GNUNET_TIME_Relative refund_deadline; - - refund_deadline - = GNUNET_TIME_absolute_get_remaining (ds->refund_deadline.abs_time); - ds->wire_deadline - = - GNUNET_TIME_relative_to_timestamp ( - GNUNET_TIME_relative_multiply (refund_deadline, - 2)); - } - else - { - ds->refund_deadline = ds->wallet_timestamp; - ds->wire_deadline = GNUNET_TIME_timestamp_get (); - } GNUNET_CRYPTO_eddsa_key_get_public (&ds->merchant_priv.eddsa_priv, &merchant_pub.eddsa_pub); { @@ -631,14 +631,15 @@ deposit_traits (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_deposit (const char *label, - const char *coin_reference, - unsigned int coin_index, - const char *target_account_payto, - const char *contract_terms, - struct GNUNET_TIME_Relative refund_deadline, - const char *amount, - unsigned int expected_response_code) +TALER_TESTING_cmd_deposit ( + const char *label, + const char *coin_reference, + unsigned int coin_index, + const char *target_account_payto, + const char *contract_terms, + struct GNUNET_TIME_Relative refund_deadline, + const char *amount, + unsigned int expected_response_code) { struct DepositState *ds; @@ -694,15 +695,16 @@ TALER_TESTING_cmd_deposit (const char *label, struct TALER_TESTING_Command -TALER_TESTING_cmd_deposit_with_ref (const char *label, - const char *coin_reference, - unsigned int coin_index, - const char *target_account_payto, - const char *contract_terms, - struct GNUNET_TIME_Relative refund_deadline, - const char *amount, - unsigned int expected_response_code, - const char *merchant_priv_reference) +TALER_TESTING_cmd_deposit_with_ref ( + const char *label, + const char *coin_reference, + unsigned int coin_index, + const char *target_account_payto, + const char *contract_terms, + struct GNUNET_TIME_Relative refund_deadline, + const char *amount, + unsigned int expected_response_code, + const char *merchant_priv_reference) { struct DepositState *ds; @@ -758,9 +760,10 @@ TALER_TESTING_cmd_deposit_with_ref (const char *label, struct TALER_TESTING_Command -TALER_TESTING_cmd_deposit_replay (const char *label, - const char *deposit_reference, - unsigned int expected_response_code) +TALER_TESTING_cmd_deposit_replay ( + const char *label, + const char *deposit_reference, + unsigned int expected_response_code) { struct DepositState *ds; diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index dd89a48d3..03e704c72 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -158,7 +158,7 @@ insert_deposit_run (void *cls, GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&denom_priv, &dpk, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, 1024)); TALER_denom_pub_hash (&dpk, &issue.denom_hash); @@ -223,19 +223,20 @@ insert_deposit_run (void *cls, struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature bds; struct TALER_PlanchetMasterSecretP ps; - struct TALER_ExchangeWithdrawValues alg_values; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; + const struct TALER_ExchangeWithdrawValues *alg_values; - alg_values.cipher = TALER_DENOMINATION_RSA; + alg_values = TALER_denom_ewv_rsa_singleton (); TALER_planchet_blinding_secret_create (&ps, - &alg_values, + alg_values, &bks); GNUNET_assert (GNUNET_OK == TALER_denom_blind (&dpk, &bks, NULL, /* no age restriction active */ + NULL, /* no nonce needed */ &deposit.coin.coin_pub, - &alg_values, + alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == @@ -249,7 +250,7 @@ insert_deposit_run (void *cls, &bds, &bks, &c_hash, - &alg_values, + alg_values, &dpk)); TALER_blinded_denom_sig_free (&bds); } diff --git a/src/testing/testing_api_cmd_oauth.c b/src/testing/testing_api_cmd_oauth.c index b086d2297..17f0eaa68 100644 --- a/src/testing/testing_api_cmd_oauth.c +++ b/src/testing/testing_api_cmd_oauth.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021 Taler Systems SA + Copyright (C) 2021-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 3b35a73b9..c5e20f2ad 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -80,7 +80,7 @@ struct TALER_TESTING_FreshCoinData /** * The blinding key (needed for recoup operations). */ - union TALER_DenominationBlindingKeyP blinding_key; + union GNUNET_CRYPTO_BlindingSecretP blinding_key; }; @@ -964,10 +964,12 @@ melt_cb (void *cls, return; } GNUNET_free (rms->mbds); - rms->mbds = GNUNET_memdup (mr->details.ok.mbds, - mr->details.ok.num_mbds - * sizeof (struct - TALER_EXCHANGE_MeltBlindingDetail)); + rms->mbds = GNUNET_new_array ( + mr->details.ok.num_mbds, + struct TALER_EXCHANGE_MeltBlindingDetail); + for (unsigned int i = 0; i<mr->details.ok.num_mbds; i++) + TALER_denom_ewv_deep_copy (&rms->mbds[i].alg_value, + &mr->details.ok.mbds[i].alg_value); } if (0 != rms->total_backoff.rel_value_us) { @@ -1059,7 +1061,6 @@ melt_run (void *cls, TALER_TESTING_interpreter_fail (rms->is); return; } - if (GNUNET_OK != TALER_TESTING_get_trait_age_commitment_proof (coin_command, 0, @@ -1079,7 +1080,6 @@ melt_run (void *cls, TALER_TESTING_interpreter_fail (rms->is); return; } - if (GNUNET_OK != TALER_TESTING_get_trait_denom_sig (coin_command, 0, @@ -1089,7 +1089,6 @@ melt_run (void *cls, TALER_TESTING_interpreter_fail (rms->is); return; } - if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub (coin_command, 0, @@ -1217,8 +1216,12 @@ melt_cleanup (void *cls, TALER_denom_pub_free (&rms->fresh_pks[i].key); GNUNET_free (rms->fresh_pks); } - - GNUNET_free (rms->mbds); + if (NULL != rms->mbds) + { + for (unsigned int i = 0; i < rms->num_fresh_coins; i++) + TALER_denom_ewv_free (&rms->mbds[i].alg_value); + GNUNET_free (rms->mbds); + } GNUNET_free (rms->melt_fresh_amounts); GNUNET_free (rms); } diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 8a88f60f7..13162a34a 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -113,7 +113,7 @@ struct WithdrawState /** * Blinding key used during the operation. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Values contributed from the exchange during the @@ -297,7 +297,8 @@ reserve_withdraw_cb (void *cls, &wr->details.ok.coins[0].sig); ws->coin_priv = wr->details.ok.coins[0].coin_priv; ws->bks = wr->details.ok.coins[0].bks; - ws->exchange_vals = wr->details.ok.coins[0].exchange_vals; + TALER_denom_ewv_deep_copy (&ws->exchange_vals, + &wr->details.ok.coins[0].exchange_vals); if (0 != ws->total_backoff.rel_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -489,6 +490,7 @@ withdraw_cleanup (void *cls, ws->retry_task = NULL; } TALER_denom_sig_free (&ws->sig); + TALER_denom_ewv_free (&ws->exchange_vals); if (NULL != ws->pk) { TALER_EXCHANGE_destroy_denomination_key (ws->pk); diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 781028bf1..0f242f7f1 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c @@ -511,14 +511,19 @@ TALER_TESTING_run2 (struct TALER_TESTING_Interpreter *is, } +#include "valgrind.h" + void TALER_TESTING_run (struct TALER_TESTING_Interpreter *is, struct TALER_TESTING_Command *commands) { TALER_TESTING_run2 (is, commands, - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, - 5)); + 0 == RUNNING_ON_VALGRIND + ? GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, + 5) + : GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, + 50)); } diff --git a/src/testing/valgrind.h b/src/testing/valgrind.h new file mode 100644 index 000000000..eaf1632e1 --- /dev/null +++ b/src/testing/valgrind.h @@ -0,0 +1,7165 @@ +/* -*- c -*- + ---------------------------------------------------------------- + + Notice that the following BSD-style license applies to this one + file (valgrind.h) only. The rest of Valgrind is licensed under the + terms of the GNU General Public License, version 2, unless + otherwise indicated. See the COPYING file in the source + distribution for details. + + ---------------------------------------------------------------- + + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2017 Julian Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ---------------------------------------------------------------- + + Notice that the above BSD-style license applies to this one file + (valgrind.h) only. The entire rest of Valgrind is licensed under + the terms of the GNU General Public License, version 2. See the + COPYING file in the source distribution for details. + + ---------------------------------------------------------------- +*/ + + +/* This file is for inclusion into client (your!) code. + + You can use these macros to manipulate and query Valgrind's + execution inside your own programs. + + The resulting executables will still run without Valgrind, just a + little bit more slowly than they otherwise would, but otherwise + unchanged. When not running on valgrind, each client request + consumes very few (eg. 7) instructions, so the resulting performance + loss is negligible unless you plan to execute client requests + millions of times per second. Nevertheless, if that is still a + problem, you can compile with the NVALGRIND symbol defined (gcc + -DNVALGRIND) so that client requests are not even compiled in. */ + +#ifndef __VALGRIND_H +#define __VALGRIND_H + + +/* ------------------------------------------------------------------ */ +/* VERSION NUMBER OF VALGRIND */ +/* ------------------------------------------------------------------ */ + +/* Specify Valgrind's version number, so that user code can + conditionally compile based on our version number. Note that these + were introduced at version 3.6 and so do not exist in version 3.5 + or earlier. The recommended way to use them to check for "version + X.Y or later" is (eg) + +#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ + && (__VALGRIND_MAJOR__ > 3 \ + || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) +*/ +#define __VALGRIND_MAJOR__ 3 +#define __VALGRIND_MINOR__ 19 + + +#include <stdarg.h> + +/* Nb: this file might be included in a file compiled with -ansi. So + we can't use C++ style "//" comments nor the "asm" keyword (instead + use "__asm__"). */ + +/* Derive some tags indicating what the target platform is. Note + that in this file we're using the compiler's CPP symbols for + identifying architectures, which are different to the ones we use + within the rest of Valgrind. Note, __powerpc__ is active for both + 32 and 64-bit PPC, whereas __powerpc64__ is only active for the + latter (on Linux, that is). + + Misc note: how to find out what's predefined in gcc by default: + gcc -Wp,-dM somefile.c +*/ +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_freebsd +#undef PLAT_amd64_freebsd +#undef PLAT_x86_win32 +#undef PLAT_amd64_win64 +#undef PLAT_x86_linux +#undef PLAT_amd64_linux +#undef PLAT_ppc32_linux +#undef PLAT_ppc64be_linux +#undef PLAT_ppc64le_linux +#undef PLAT_arm_linux +#undef PLAT_arm64_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux +#undef PLAT_mips64_linux +#undef PLAT_nanomips_linux +#undef PLAT_x86_solaris +#undef PLAT_amd64_solaris + + +#if defined(__APPLE__) && defined(__i386__) +# define PLAT_x86_darwin 1 +#elif defined(__APPLE__) && defined(__x86_64__) +# define PLAT_amd64_darwin 1 +#elif defined(__FreeBSD__) && defined(__i386__) +# define PLAT_x86_freebsd 1 +#elif defined(__FreeBSD__) && defined(__amd64__) +# define PLAT_amd64_freebsd 1 +#elif (defined(__MINGW32__) && defined(__i386__)) \ + || defined(__CYGWIN32__) \ + || (defined(_WIN32) && defined(_M_IX86)) +# define PLAT_x86_win32 1 +#elif (defined(__MINGW32__) && defined(__x86_64__)) \ + || (defined(_WIN32) && defined(_M_X64)) +/* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */ +# define PLAT_amd64_win64 1 +#elif defined(__linux__) && defined(__i386__) +# define PLAT_x86_linux 1 +#elif defined(__linux__) && defined(__x86_64__) && !defined(__ILP32__) +# define PLAT_amd64_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) +# define PLAT_ppc32_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2 +/* Big Endian uses ELF version 1 */ +# define PLAT_ppc64be_linux 1 +#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2 +/* Little Endian uses ELF version 2 */ +# define PLAT_ppc64le_linux 1 +#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) +# define PLAT_arm_linux 1 +#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) +# define PLAT_arm64_linux 1 +#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) +# define PLAT_s390x_linux 1 +#elif defined(__linux__) && defined(__mips__) && (__mips==64) +# define PLAT_mips64_linux 1 +#elif defined(__linux__) && defined(__mips__) && (__mips==32) +# define PLAT_mips32_linux 1 +#elif defined(__linux__) && defined(__nanomips__) +# define PLAT_nanomips_linux 1 +#elif defined(__sun) && defined(__i386__) +# define PLAT_x86_solaris 1 +#elif defined(__sun) && defined(__x86_64__) +# define PLAT_amd64_solaris 1 +#else +/* If we're not compiling for our target platform, don't generate + any inline asms. */ +# if !defined(NVALGRIND) +# define NVALGRIND 1 +# endif +#endif + + +/* ------------------------------------------------------------------ */ +/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ +/* in here of use to end-users -- skip to the next section. */ +/* ------------------------------------------------------------------ */ + +/* + * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client + * request. Accepts both pointers and integers as arguments. + * + * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind + * client request that does not return a value. + + * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind + * client request and whose value equals the client request result. Accepts + * both pointers and integers as arguments. Note that such calls are not + * necessarily pure functions -- they may have side effects. + */ + +#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ + _zzq_request, _zzq_arg1, _zzq_arg2, \ + _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + +#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ + _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + +#if defined(NVALGRIND) + +/* Define NVALGRIND to completely remove the Valgrind magic sequence + from the compiled code (analogous to NDEBUG's effects on + assert()) */ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + (_zzq_default) + +#else /* ! NVALGRIND */ + +/* The following defines the magic code sequences which the JITter + spots and handles magically. Don't look too closely at them as + they will rot your brain. + + The assembly code sequences for all architectures is in this one + file. This is because this file must be stand-alone, and we don't + want to have multiple files. + + For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default + value gets put in the return slot, so that everything works when + this is executed not under Valgrind. Args are passed in a memory + block, and so there's no intrinsic limit to the number that could + be passed, but it's currently five. + + The macro args are: + _zzq_rlval result lvalue + _zzq_default default value (result returned when running on real CPU) + _zzq_request request code + _zzq_arg1..5 request params + + The other two macros are used to support function wrapping, and are + a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the + guest's NRADDR pseudo-register and whatever other information is + needed to safely run the call original from the wrapper: on + ppc64-linux, the R2 value at the divert point is also needed. This + information is abstracted into a user-visible type, OrigFn. + + VALGRIND_CALL_NOREDIR_* behaves the same as the following on the + guest, but guarantees that the branch instruction will not be + redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: + branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a + complete inline asm, since it needs to be combined with more magic + inline asm stuff to be useful. +*/ + +/* ----------------- x86-{linux,darwin,solaris} ---------------- */ + +#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ + || (defined(PLAT_x86_win32) && defined(__GNUC__)) \ + || defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "roll $3, %%edi ; roll $13, %%edi\n\t" \ + "roll $29, %%edi ; roll $19, %%edi\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EDX = client_request ( %EAX ) */ \ + "xchgl %%ebx,%%ebx" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EAX = guest_NRADDR */ \ + "xchgl %%ecx,%%ecx" \ + : "=a" (__addr) \ + : \ + : "cc", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_EAX \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%EAX */ \ + "xchgl %%edx,%%edx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgl %%edi,%%edi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) + || PLAT_x86_solaris */ + +/* ------------------------- x86-Win32 ------------------------- */ + +#if defined(PLAT_x86_win32) && !defined(__GNUC__) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#if defined(_MSC_VER) + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm rol edi, 3 __asm rol edi, 13 \ + __asm rol edi, 29 __asm rol edi, 19 + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ + (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ + (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ + (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) + +static __inline uintptr_t +valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, + uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, + uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, + uintptr_t _zzq_arg5) +{ + volatile uintptr_t _zzq_args[6]; + volatile unsigned int _zzq_result; + _zzq_args[0] = (uintptr_t)(_zzq_request); + _zzq_args[1] = (uintptr_t)(_zzq_arg1); + _zzq_args[2] = (uintptr_t)(_zzq_arg2); + _zzq_args[3] = (uintptr_t)(_zzq_arg3); + _zzq_args[4] = (uintptr_t)(_zzq_arg4); + _zzq_args[5] = (uintptr_t)(_zzq_arg5); + __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default + __SPECIAL_INSTRUCTION_PREAMBLE + /* %EDX = client_request ( %EAX ) */ + __asm xchg ebx,ebx + __asm mov _zzq_result, edx + } + return _zzq_result; +} + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EAX = guest_NRADDR */ \ + __asm xchg ecx,ecx \ + __asm mov __addr, eax \ + } \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_EAX ERROR + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm xchg edi,edi \ + } \ + } while (0) + +#else +#error Unsupported compiler. +#endif + +#endif /* PLAT_x86_win32 */ + +/* ----------------- amd64-{linux,darwin,solaris} --------------- */ + +#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ + || defined(PLAT_amd64_solaris) \ + || defined(PLAT_amd64_freebsd) \ + || (defined(PLAT_amd64_win64) && defined(__GNUC__)) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ + "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RDX = client_request ( %RAX ) */ \ + "xchgq %%rbx,%%rbx" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %RAX = guest_NRADDR */ \ + "xchgq %%rcx,%%rcx" \ + : "=a" (__addr) \ + : \ + : "cc", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_RAX \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%RAX */ \ + "xchgq %%rdx,%%rdx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgq %%rdi,%%rdi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ + +/* ------------------------- amd64-Win64 ------------------------- */ + +#if defined(PLAT_amd64_win64) && !defined(__GNUC__) + +#error Unsupported compiler. + +#endif /* PLAT_amd64_win64 */ + +/* ------------------------ ppc32-linux ------------------------ */ + +#if defined(PLAT_ppc32_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rlwinm 0,0,3,0,31 ; rlwinm 0,0,13,0,31\n\t" \ + "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned int _zzq_args[6]; \ + unsigned int _zzq_result; \ + unsigned int* _zzq_ptr; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R11 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc32_linux */ + +/* ------------------------ ppc64-linux ------------------------ */ + +#if defined(PLAT_ppc64be_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + unsigned long int r2; /* what tocptr do we need? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ + "rotldi 0,0,61 ; rotldi 0,0,51\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned long int _zzq_args[6]; \ + unsigned long int _zzq_result; \ + unsigned long int* _zzq_ptr; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR_GPR2 */ \ + "or 4,4,4\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->r2 = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R11 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc64be_linux */ + +#if defined(PLAT_ppc64le_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + unsigned long int r2; /* what tocptr do we need? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ + "rotldi 0,0,61 ; rotldi 0,0,51\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({ unsigned long int _zzq_args[6]; \ + unsigned long int _zzq_result; \ + unsigned long int* _zzq_ptr; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + _zzq_ptr = _zzq_args; \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = client_request ( %R4 ) */ \ + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR */ \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %R3 = guest_NRADDR_GPR2 */ \ + "or 4,4,4\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->r2 = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R12 */ \ + "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_ppc64le_linux */ + +/* ------------------------- arm-linux ------------------------- */ + +#if defined(PLAT_arm_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ + "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("mov r3, %1\n\t" /*default*/ \ + "mov r4, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* R3 = client_request ( R4 ) */ \ + "orr r10, r10, r10\n\t" \ + "mov %0, r3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "cc","memory", "r3", "r4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* R3 = guest_NRADDR */ \ + "orr r11, r11, r11\n\t" \ + "mov %0, r3" \ + : "=r" (__addr) \ + : \ + : "cc", "memory", "r3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir *%R4 */ \ + "orr r12, r12, r12\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "orr r9, r9, r9\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_arm_linux */ + +/* ------------------------ arm64-linux ------------------------- */ + +#if defined(PLAT_arm64_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "ror x12, x12, #3 ; ror x12, x12, #13 \n\t" \ + "ror x12, x12, #51 ; ror x12, x12, #61 \n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + \ + __extension__ \ + ({volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile("mov x3, %1\n\t" /*default*/ \ + "mov x4, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* X3 = client_request ( X4 ) */ \ + "orr x10, x10, x10\n\t" \ + "mov %0, x3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" ((unsigned long int)(_zzq_default)), \ + "r" (&_zzq_args[0]) \ + : "cc","memory", "x3", "x4"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* X3 = guest_NRADDR */ \ + "orr x11, x11, x11\n\t" \ + "mov %0, x3" \ + : "=r" (__addr) \ + : \ + : "cc", "memory", "x3" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* branch-and-link-to-noredir X8 */ \ + "orr x12, x12, x12\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "orr x9, x9, x9\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_arm64_linux */ + +/* ------------------------ s390x-linux ------------------------ */ + +#if defined(PLAT_s390x_linux) + +typedef + struct { + unsigned long int nraddr; /* where's the code? */ + } + OrigFn; + +/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific + * code. This detection is implemented in platform specific toIR.c + * (e.g. VEX/priv/guest_s390_decoder.c). + */ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "lr 15,15\n\t" \ + "lr 1,1\n\t" \ + "lr 2,2\n\t" \ + "lr 3,3\n\t" + +#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" +#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" +#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" +#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile(/* r2 = args */ \ + "lgr 2,%1\n\t" \ + /* r3 = default */ \ + "lgr 3,%2\n\t" \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CLIENT_REQUEST_CODE \ + /* results = r3 */ \ + "lgr %0, 3\n\t" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), \ + "0" ((unsigned long int)_zzq_default) \ + : "cc", "2", "3", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __GET_NR_CONTEXT_CODE \ + "lgr %0, 3\n\t" \ + : "=a" (__addr) \ + : \ + : "cc", "3", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_R1 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CALL_NO_REDIR_CODE + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __VEX_INJECT_IR_CODE); \ + } while (0) + +#endif /* PLAT_s390x_linux */ + +/* ------------------------- mips32-linux ---------------- */ + +#if defined(PLAT_mips32_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +/* .word 0x342 + * .word 0x742 + * .word 0xC2 + * .word 0x4C2*/ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "srl $0, $0, 13\n\t" \ + "srl $0, $0, 29\n\t" \ + "srl $0, $0, 3\n\t" \ + "srl $0, $0, 19\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("move $11, %1\n\t" /*default*/ \ + "move $12, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* T3 = client_request ( T4 ) */ \ + "or $13, $13, $13\n\t" \ + "move %0, $11\n\t" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "$11", "$12", "memory"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* %t9 = guest_NRADDR */ \ + "or $14, $14, $14\n\t" \ + "move %0, $11" /*result*/ \ + : "=r" (__addr) \ + : \ + : "$11" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%t9 */ \ + "or $15, $15, $15\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or $11, $11, $11\n\t" \ + ); \ + } while (0) + + +#endif /* PLAT_mips32_linux */ + +/* ------------------------- mips64-linux ---------------- */ + +#if defined(PLAT_mips64_linux) + +typedef + struct { + unsigned long nraddr; /* where's the code? */ + } + OrigFn; + +/* dsll $0,$0, 3 + * dsll $0,$0, 13 + * dsll $0,$0, 29 + * dsll $0,$0, 19*/ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \ + "dsll $0,$0,29 ; dsll $0,$0,19\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned long int _zzq_args[6]; \ + volatile unsigned long int _zzq_result; \ + _zzq_args[0] = (unsigned long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long int)(_zzq_arg5); \ + __asm__ volatile("move $11, %1\n\t" /*default*/ \ + "move $12, %2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* $11 = client_request ( $12 ) */ \ + "or $13, $13, $13\n\t" \ + "move %0, $11\n\t" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "$11", "$12", "memory"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* $11 = guest_NRADDR */ \ + "or $14, $14, $14\n\t" \ + "move %0, $11" /*result*/ \ + : "=r" (__addr) \ + : \ + : "$11"); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir $25 */ \ + "or $15, $15, $15\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or $11, $11, $11\n\t" \ + ); \ + } while (0) + +#endif /* PLAT_mips64_linux */ + +#if defined(PLAT_nanomips_linux) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; +/* + 8000 c04d srl zero, zero, 13 + 8000 c05d srl zero, zero, 29 + 8000 c043 srl zero, zero, 3 + 8000 c053 srl zero, zero, 19 +*/ + +#define __SPECIAL_INSTRUCTION_PREAMBLE "srl[32] $zero, $zero, 13 \n\t" \ + "srl[32] $zero, $zero, 29 \n\t" \ + "srl[32] $zero, $zero, 3 \n\t" \ + "srl[32] $zero, $zero, 19 \n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("move $a7, %1\n\t" /* default */ \ + "move $t0, %2\n\t" /* ptr */ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* $a7 = client_request( $t0 ) */ \ + "or[32] $t0, $t0, $t0\n\t" \ + "move %0, $a7\n\t" /* result */ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "$a7", "$t0", "memory"); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + /* $a7 = guest_NRADDR */ \ + "or[32] $t1, $t1, $t1\n\t" \ + "move %0, $a7" /*result*/ \ + : "=r" (__addr) \ + : \ + : "$a7"); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir $25 */ \ + "or[32] $t2, $t2, $t2\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or[32] $t3, $t3, $t3\n\t" \ + ); \ + } while (0) + +#endif +/* Insert assembly code for other platforms here... */ + +#endif /* NVALGRIND */ + + +/* ------------------------------------------------------------------ */ +/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ +/* ugly. It's the least-worst tradeoff I can think of. */ +/* ------------------------------------------------------------------ */ + +/* This section defines magic (a.k.a appalling-hack) macros for doing + guaranteed-no-redirection macros, so as to get from function + wrappers to the functions they are wrapping. The whole point is to + construct standard call sequences, but to do the call itself with a + special no-redirect call pseudo-instruction that the JIT + understands and handles specially. This section is long and + repetitious, and I can't see a way to make it shorter. + + The naming scheme is as follows: + + CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} + + 'W' stands for "word" and 'v' for "void". Hence there are + different macros for calling arity 0, 1, 2, 3, 4, etc, functions, + and for each, the possibility of returning a word-typed result, or + no result. +*/ + +/* Use these to write the name of your wrapper. NOTE: duplicates + VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts + the default behaviour equivalance class tag "0000" into the name. + See pub_tool_redir.h for details -- normally you don't need to + think about this, though. */ + +/* Use an extra level of macroisation so as to ensure the soname/fnname + args are fully macro-expanded before pasting them together. */ +#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd + +#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ + VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) + +#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ + VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) + +/* Use this macro from within a wrapper function to collect the + context (address and possibly other info) of the original function. + Once you have that you can then use it in one of the CALL_FN_ + macros. The type of the argument _lval is OrigFn. */ +#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) + +/* Also provide end-user facilities for function replacement, rather + than wrapping. A replacement function differs from a wrapper in + that it has no way to get hold of the original function being + called, and hence no way to call onwards to it. In a replacement + function, VALGRIND_GET_ORIG_FN always returns zero. */ + +#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ + VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) + +#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ + VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) + +/* Derivatives of the main macros below, for calling functions + returning void. */ + +#define CALL_FN_v_v(fnptr) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_v(_junk,fnptr); } while (0) + +#define CALL_FN_v_W(fnptr, arg1) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_W(_junk,fnptr,arg1); } while (0) + +#define CALL_FN_v_WW(fnptr, arg1,arg2) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) + +#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) + +#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) + +#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) + +#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) + +#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ + do { volatile unsigned long _junk; \ + CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) + +/* ----------------- x86-{linux,darwin,solaris} ---------------- */ + +#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ + || defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd) + +/* These regs are trashed by the hidden call. No need to mention eax + as gcc can already see that, plus causes gcc to bomb. */ +#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movl %%esp,%%edi\n\t" \ + "andl $0xfffffff0,%%esp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movl %%edi,%%esp\n\t" + +/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ + "pushl 44(%%eax)\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "pushl 48(%%eax)\n\t" \ + "pushl 44(%%eax)\n\t" \ + "pushl 40(%%eax)\n\t" \ + "pushl 36(%%eax)\n\t" \ + "pushl 32(%%eax)\n\t" \ + "pushl 28(%%eax)\n\t" \ + "pushl 24(%%eax)\n\t" \ + "pushl 20(%%eax)\n\t" \ + "pushl 16(%%eax)\n\t" \ + "pushl 12(%%eax)\n\t" \ + "pushl 8(%%eax)\n\t" \ + "pushl 4(%%eax)\n\t" \ + "movl (%%eax), %%eax\n\t" /* target->%eax */ \ + VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */ + +/* ---------------- amd64-{linux,darwin,solaris} --------------- */ + +#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ + || defined(PLAT_amd64_solaris) || defined(PLAT_amd64_freebsd) + +/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ + "rdi", "r8", "r9", "r10", "r11" + +/* This is all pretty complex. It's so as to make stack unwinding + work reliably. See bug 243270. The basic problem is the sub and + add of 128 of %rsp in all of the following macros. If gcc believes + the CFA is in %rsp, then unwinding may fail, because what's at the + CFA is not what gcc "expected" when it constructs the CFIs for the + places where the macros are instantiated. + + But we can't just add a CFI annotation to increase the CFA offset + by 128, to match the sub of 128 from %rsp, because we don't know + whether gcc has chosen %rsp as the CFA at that point, or whether it + has chosen some other register (eg, %rbp). In the latter case, + adding a CFI annotation to change the CFA offset is simply wrong. + + So the solution is to get hold of the CFA using + __builtin_dwarf_cfa(), put it in a known register, and add a + CFI annotation to say what the register is. We choose %rbp for + this (perhaps perversely), because: + + (1) %rbp is already subject to unwinding. If a new register was + chosen then the unwinder would have to unwind it in all stack + traces, which is expensive, and + + (2) %rbp is already subject to precise exception updates in the + JIT. If a new register was chosen, we'd have to have precise + exceptions for it too, which reduces performance of the + generated code. + + However .. one extra complication. We can't just whack the result + of __builtin_dwarf_cfa() into %rbp and then add %rbp to the + list of trashed registers at the end of the inline assembly + fragments; gcc won't allow %rbp to appear in that list. Hence + instead we need to stash %rbp in %r15 for the duration of the asm, + and say that %r15 is trashed instead. gcc seems happy to go with + that. + + Oh .. and this all needs to be conditionalised so that it is + unchanged from before this commit, when compiled with older gccs + that don't support __builtin_dwarf_cfa. Furthermore, since + this header file is freestanding, it has to be independent of + config.h, and so the following conditionalisation cannot depend on + configure time checks. + + Although it's not clear from + 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', + this expression excludes Darwin. + .cfi directives in Darwin assembly appear to be completely + different and I haven't investigated how they work. + + For even more entertainment value, note we have to use the + completely undocumented __builtin_dwarf_cfa(), which appears to + really compute the CFA, whereas __builtin_frame_address(0) claims + to but actually doesn't. See + https://bugs.kde.org/show_bug.cgi?id=243270#c47 +*/ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"r"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + "movq %%rbp, %%r15\n\t" \ + "movq %2, %%rbp\n\t" \ + ".cfi_remember_state\n\t" \ + ".cfi_def_cfa rbp, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "movq %%r15, %%rbp\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE +# define VALGRIND_CFI_EPILOGUE +#endif + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movq %%rsp,%%r14\n\t" \ + "andq $0xfffffffffffffff0,%%rsp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movq %%r14,%%rsp\n\t" + +/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned + long) == 8. */ + +/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ + macros. In order not to trash the stack redzone, we need to drop + %rsp by 128 before the hidden call, and restore afterwards. The + nastyness is that it is only by luck that the stack still appears + to be unwindable during the hidden call - since then the behaviour + of any routine using this macro does not match what the CFI data + says. Sigh. + + Why is this important? Imagine that a wrapper has a stack + allocated local, and passes to the hidden call, a pointer to it. + Because gcc does not know about the hidden call, it may allocate + that local in the redzone. Unfortunately the hidden call may then + trash it before it comes to use it. So we must step clear of the + redzone, for the duration of the hidden call, to make it safe. + + Probably the same problem afflicts the other redzone-style ABIs too + (ppc64-linux); but for those, the stack is + self describing (none of this CFI nonsense) so at least messing + with the stack pointer doesn't give a danger of non-unwindable + stack. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 96(%%rax)\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */ + +/* ------------------------ ppc32-linux ------------------------ */ + +#if defined(PLAT_ppc32_linux) + +/* This is useful for finding out about the on-stack stuff: + + extern int f9 ( int,int,int,int,int,int,int,int,int ); + extern int f10 ( int,int,int,int,int,int,int,int,int,int ); + extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); + extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); + + int g9 ( void ) { + return f9(11,22,33,44,55,66,77,88,99); + } + int g10 ( void ) { + return f10(11,22,33,44,55,66,77,88,99,110); + } + int g11 ( void ) { + return f11(11,22,33,44,55,66,77,88,99,110,121); + } + int g12 ( void ) { + return f12(11,22,33,44,55,66,77,88,99,110,121,132); + } +*/ + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rlwinm 1,1,0,0,27\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc32-linux, + sizeof(unsigned long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg12 */ \ + "lwz 3,48(11)\n\t" \ + "stw 3,20(1)\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc32_linux */ + +/* ------------------------ ppc64-linux ------------------------ */ + +#if defined(PLAT_ppc64be_linux) + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rldicr 1,1,0,59\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned + long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg11 */ \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + _argvec[2+12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg12 */ \ + "ld 3,96(11)\n\t" \ + "std 3,136(1)\n\t" \ + /* arg11 */ \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc64be_linux */ + +/* ------------------------- ppc64le-linux ----------------------- */ +#if defined(PLAT_ppc64le_linux) + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rldicr 1,1,0,59\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned + long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg11 */ \ + "ld 3,88(12)\n\t" \ + "std 3,112(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _res; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + _argvec[2+12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "mr 12,%1\n\t" \ + "std 2,-16(12)\n\t" /* save tocptr */ \ + "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ + /* arg12 */ \ + "ld 3,96(12)\n\t" \ + "std 3,120(1)\n\t" \ + /* arg11 */ \ + "ld 3,88(12)\n\t" \ + "std 3,112(1)\n\t" \ + /* arg10 */ \ + "ld 3,80(12)\n\t" \ + "std 3,104(1)\n\t" \ + /* arg9 */ \ + "ld 3,72(12)\n\t" \ + "std 3,96(1)\n\t" \ + /* args1-8 */ \ + "ld 3, 8(12)\n\t" /* arg1->r3 */ \ + "ld 4, 16(12)\n\t" /* arg2->r4 */ \ + "ld 5, 24(12)\n\t" /* arg3->r5 */ \ + "ld 6, 32(12)\n\t" /* arg4->r6 */ \ + "ld 7, 40(12)\n\t" /* arg5->r7 */ \ + "ld 8, 48(12)\n\t" /* arg6->r8 */ \ + "ld 9, 56(12)\n\t" /* arg7->r9 */ \ + "ld 10, 64(12)\n\t" /* arg8->r10 */ \ + "ld 12, 0(12)\n\t" /* target->r12 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ + "mr 12,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(12)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_ppc64le_linux */ + +/* ------------------------- arm-linux ------------------------- */ + +#if defined(PLAT_arm_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4", "r12", "r14" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +/* This is a bit tricky. We store the original stack pointer in r10 + as it is callee-saves. gcc doesn't allow the use of r11 for some + reason. Also, we can't directly "bic" the stack pointer in thumb + mode since r13 isn't an allowed register number in that context. + So use r4 as a temporary, since that is about to get trashed + anyway, just after each use of this macro. Side effect is we need + to be very careful about any future changes, since + VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ +#define VALGRIND_ALIGN_STACK \ + "mov r10, sp\n\t" \ + "mov r4, sp\n\t" \ + "bic r4, r4, #7\n\t" \ + "mov sp, r4\n\t" +#define VALGRIND_RESTORE_STACK \ + "mov sp, r10\n\t" + +/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "push {r0, r1, r2, r3} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "ldr r2, [%1, #48] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_arm_linux */ + +/* ------------------------ arm64-linux ------------------------ */ + +#if defined(PLAT_arm64_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9", \ + "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \ + "x18", "x19", "x20", "x30", \ + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \ + "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \ + "v26", "v27", "v28", "v29", "v30", "v31" + +/* x21 is callee-saved, so we can use it to save and restore SP around + the hidden call. */ +#define VALGRIND_ALIGN_STACK \ + "mov x21, sp\n\t" \ + "bic sp, x21, #15\n\t" +#define VALGRIND_RESTORE_STACK \ + "mov sp, x21\n\t" + +/* These CALL_FN_ macros assume that on arm64-linux, + sizeof(unsigned long) == 8. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x20 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x20 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x30 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1, #88] \n\t" \ + "str x8, [sp, #16] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11, \ + arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #0x30 \n\t" \ + "ldr x0, [%1, #8] \n\t" \ + "ldr x1, [%1, #16] \n\t" \ + "ldr x2, [%1, #24] \n\t" \ + "ldr x3, [%1, #32] \n\t" \ + "ldr x4, [%1, #40] \n\t" \ + "ldr x5, [%1, #48] \n\t" \ + "ldr x6, [%1, #56] \n\t" \ + "ldr x7, [%1, #64] \n\t" \ + "ldr x8, [%1, #72] \n\t" \ + "str x8, [sp, #0] \n\t" \ + "ldr x8, [%1, #80] \n\t" \ + "str x8, [sp, #8] \n\t" \ + "ldr x8, [%1, #88] \n\t" \ + "str x8, [sp, #16] \n\t" \ + "ldr x8, [%1, #96] \n\t" \ + "str x8, [sp, #24] \n\t" \ + "ldr x8, [%1] \n\t" /* target->x8 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ + VALGRIND_RESTORE_STACK \ + "mov %0, x0" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_arm64_linux */ + +/* ------------------------- s390x-linux ------------------------- */ + +#if defined(PLAT_s390x_linux) + +/* Similar workaround as amd64 (see above), but we use r11 as frame + pointer and save the old r11 in r7. r11 might be used for + argvec, therefore we copy argvec in r1 since r1 is clobbered + after the call anyway. */ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"d"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + ".cfi_remember_state\n\t" \ + "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ + "lgr 7,11\n\t" \ + "lgr 11,%2\n\t" \ + ".cfi_def_cfa r11, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "lgr 11, 7\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE \ + "lgr 1,%1\n\t" +# define VALGRIND_CFI_EPILOGUE +#endif + +/* Nb: On s390 the stack pointer is properly aligned *at all times* + according to the s390 GCC maintainer. (The ABI specification is not + precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and + VALGRIND_RESTORE_STACK are not defined here. */ + +/* These regs are trashed by the hidden call. Note that we overwrite + r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the + function a proper return address. All others are ABI defined call + clobbers. */ +#if defined(__VX__) || defined(__S390_VX__) +#define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \ + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \ + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \ + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \ + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" +#else +#define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7" +#endif + +/* Nb: Although r11 is modified in the asm snippets below (inside + VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for + two reasons: + (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not + modified + (2) GCC will complain that r11 cannot appear inside a clobber section, + when compiled with -O -fno-omit-frame-pointer + */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 1, 0(1)\n\t" /* target->r1 */ \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +/* The call abi has the arguments in r2-r6 and stack */ +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-168\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,168\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-176\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,176\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-184\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,184\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-192\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,192\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-200\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,200\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-208\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,208\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-216\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "mvc 208(8,15), 96(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "aghi 15,216\n\t" \ + VALGRIND_CFI_EPILOGUE \ + "lgr %0, 2\n\t" \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + + +#endif /* PLAT_s390x_linux */ + +/* ------------------------- mips32-linux ----------------------- */ + +#if defined(PLAT_mips32_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ +"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ +"$25", "$31" + +/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16\n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" /* arg1*/ \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 24\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 24 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 32\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "nop\n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 32 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 32\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 32 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 40\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 40 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 40\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 40 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 48\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 48 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 48\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 44(%1) \n\t" \ + "sw $4, 40($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 48 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + "subu $29, $29, 8 \n\t" \ + "sw $28, 0($29) \n\t" \ + "sw $31, 4($29) \n\t" \ + "lw $4, 20(%1) \n\t" \ + "subu $29, $29, 56\n\t" \ + "sw $4, 16($29) \n\t" \ + "lw $4, 24(%1) \n\t" \ + "sw $4, 20($29) \n\t" \ + "lw $4, 28(%1) \n\t" \ + "sw $4, 24($29) \n\t" \ + "lw $4, 32(%1) \n\t" \ + "sw $4, 28($29) \n\t" \ + "lw $4, 36(%1) \n\t" \ + "sw $4, 32($29) \n\t" \ + "lw $4, 40(%1) \n\t" \ + "sw $4, 36($29) \n\t" \ + "lw $4, 44(%1) \n\t" \ + "sw $4, 40($29) \n\t" \ + "lw $4, 48(%1) \n\t" \ + "sw $4, 44($29) \n\t" \ + "lw $4, 4(%1) \n\t" \ + "lw $5, 8(%1) \n\t" \ + "lw $6, 12(%1) \n\t" \ + "lw $7, 16(%1) \n\t" \ + "lw $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 56 \n\t" \ + "lw $28, 0($29) \n\t" \ + "lw $31, 4($29) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_mips32_linux */ + +/* ------------------------- nanomips-linux -------------------- */ + +#if defined(PLAT_nanomips_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$t4", "$t5", "$a0", "$a1", "$a2", \ +"$a3", "$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3", \ +"$t8","$t9", "$at" + +/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned + long) == 4. */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + "lw $a3,16(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + "lw $a3,16(%1)\n\t" \ + "lw $a4,20(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + "lw $a3,16(%1)\n\t" \ + "lw $a4,20(%1)\n\t" \ + "lw $a5,24(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + "lw $a3,16(%1)\n\t" \ + "lw $a4,20(%1)\n\t" \ + "lw $a5,24(%1)\n\t" \ + "lw $a6,28(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + "lw $t9, 0(%1)\n\t" \ + "lw $a0, 4(%1)\n\t" \ + "lw $a1, 8(%1)\n\t" \ + "lw $a2,12(%1)\n\t" \ + "lw $a3,16(%1)\n\t" \ + "lw $a4,20(%1)\n\t" \ + "lw $a5,24(%1)\n\t" \ + "lw $a6,28(%1)\n\t" \ + "lw $a7,32(%1)\n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + "addiu $sp, $sp, -16 \n\t" \ + "lw $t9,36(%1) \n\t" \ + "sw $t9, 0($sp) \n\t" \ + "lw $t9, 0(%1) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2,12(%1) \n\t" \ + "lw $a3,16(%1) \n\t" \ + "lw $a4,20(%1) \n\t" \ + "lw $a5,24(%1) \n\t" \ + "lw $a6,28(%1) \n\t" \ + "lw $a7,32(%1) \n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0 \n\t" \ + "addiu $sp, $sp, 16 \n\t" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + "addiu $sp, $sp, -16 \n\t" \ + "lw $t9,36(%1) \n\t" \ + "sw $t9, 0($sp) \n\t" \ + "lw $t9,40(%1) \n\t" \ + "sw $t9, 4($sp) \n\t" \ + "lw $t9, 0(%1) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2,12(%1) \n\t" \ + "lw $a3,16(%1) \n\t" \ + "lw $a4,20(%1) \n\t" \ + "lw $a5,24(%1) \n\t" \ + "lw $a6,28(%1) \n\t" \ + "lw $a7,32(%1) \n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0 \n\t" \ + "addiu $sp, $sp, 16 \n\t" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + "addiu $sp, $sp, -16 \n\t" \ + "lw $t9,36(%1) \n\t" \ + "sw $t9, 0($sp) \n\t" \ + "lw $t9,40(%1) \n\t" \ + "sw $t9, 4($sp) \n\t" \ + "lw $t9,44(%1) \n\t" \ + "sw $t9, 8($sp) \n\t" \ + "lw $t9, 0(%1) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2,12(%1) \n\t" \ + "lw $a3,16(%1) \n\t" \ + "lw $a4,20(%1) \n\t" \ + "lw $a5,24(%1) \n\t" \ + "lw $a6,28(%1) \n\t" \ + "lw $a7,32(%1) \n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0 \n\t" \ + "addiu $sp, $sp, 16 \n\t" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + "addiu $sp, $sp, -16 \n\t" \ + "lw $t9,36(%1) \n\t" \ + "sw $t9, 0($sp) \n\t" \ + "lw $t9,40(%1) \n\t" \ + "sw $t9, 4($sp) \n\t" \ + "lw $t9,44(%1) \n\t" \ + "sw $t9, 8($sp) \n\t" \ + "lw $t9,48(%1) \n\t" \ + "sw $t9,12($sp) \n\t" \ + "lw $t9, 0(%1) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2,12(%1) \n\t" \ + "lw $a3,16(%1) \n\t" \ + "lw $a4,20(%1) \n\t" \ + "lw $a5,24(%1) \n\t" \ + "lw $a6,28(%1) \n\t" \ + "lw $a7,32(%1) \n\t" \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $a0 \n\t" \ + "addiu $sp, $sp, 16 \n\t" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_nanomips_linux */ + +/* ------------------------- mips64-linux ------------------------- */ + +#if defined(PLAT_mips64_linux) + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ +"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ +"$25", "$31" + +/* These CALL_FN_ macros assume that on mips64-linux, + sizeof(long long) == 8. */ + +#define MIPS64_LONG2REG_CAST(x) ((long long)(long)x) + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[1]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + __asm__ volatile( \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[2]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" /* arg1*/ \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[3]; \ + volatile unsigned long long _res; \ + _argvec[0] = _orig.nraddr; \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[4]; \ + volatile unsigned long long _res; \ + _argvec[0] = _orig.nraddr; \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[5]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[6]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[7]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[8]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[9]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + __asm__ volatile( \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[10]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + __asm__ volatile( \ + "dsubu $29, $29, 8\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 8\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[11]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + __asm__ volatile( \ + "dsubu $29, $29, 16\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 16\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[12]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \ + __asm__ volatile( \ + "dsubu $29, $29, 24\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 88(%1)\n\t" \ + "sd $4, 16($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 24\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long long _argvec[13]; \ + volatile unsigned long long _res; \ + _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr); \ + _argvec[1] = MIPS64_LONG2REG_CAST(arg1); \ + _argvec[2] = MIPS64_LONG2REG_CAST(arg2); \ + _argvec[3] = MIPS64_LONG2REG_CAST(arg3); \ + _argvec[4] = MIPS64_LONG2REG_CAST(arg4); \ + _argvec[5] = MIPS64_LONG2REG_CAST(arg5); \ + _argvec[6] = MIPS64_LONG2REG_CAST(arg6); \ + _argvec[7] = MIPS64_LONG2REG_CAST(arg7); \ + _argvec[8] = MIPS64_LONG2REG_CAST(arg8); \ + _argvec[9] = MIPS64_LONG2REG_CAST(arg9); \ + _argvec[10] = MIPS64_LONG2REG_CAST(arg10); \ + _argvec[11] = MIPS64_LONG2REG_CAST(arg11); \ + _argvec[12] = MIPS64_LONG2REG_CAST(arg12); \ + __asm__ volatile( \ + "dsubu $29, $29, 32\n\t" \ + "ld $4, 72(%1)\n\t" \ + "sd $4, 0($29)\n\t" \ + "ld $4, 80(%1)\n\t" \ + "sd $4, 8($29)\n\t" \ + "ld $4, 88(%1)\n\t" \ + "sd $4, 16($29)\n\t" \ + "ld $4, 96(%1)\n\t" \ + "sd $4, 24($29)\n\t" \ + "ld $4, 8(%1)\n\t" \ + "ld $5, 16(%1)\n\t" \ + "ld $6, 24(%1)\n\t" \ + "ld $7, 32(%1)\n\t" \ + "ld $8, 40(%1)\n\t" \ + "ld $9, 48(%1)\n\t" \ + "ld $10, 56(%1)\n\t" \ + "ld $11, 64(%1)\n\t" \ + "ld $25, 0(%1)\n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "daddu $29, $29, 32\n\t" \ + "move %0, $2\n" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "memory", __CALLER_SAVED_REGS \ + ); \ + lval = (__typeof__(lval)) (long)_res; \ + } while (0) + +#endif /* PLAT_mips64_linux */ + +/* ------------------------------------------------------------------ */ +/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ +/* */ +/* ------------------------------------------------------------------ */ + +/* Some request codes. There are many more of these, but most are not + exposed to end-user view. These are the public ones, all of the + form 0x1000 + small_number. + + Core ones are in the range 0x00000000--0x0000ffff. The non-public + ones start at 0x2000. +*/ + +/* These macros are used by tools -- they must be public, but don't + embed them into other programs. */ +#define VG_USERREQ_TOOL_BASE(a,b) \ + ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) +#define VG_IS_TOOL_USERREQ(a, b, v) \ + (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) + +/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! + This enum comprises an ABI exported by Valgrind to programs + which use client requests. DO NOT CHANGE THE NUMERIC VALUES OF THESE + ENTRIES, NOR DELETE ANY -- add new ones at the end of the most + relevant group. */ +typedef + enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, + VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, + + /* These allow any function to be called from the simulated + CPU but run on the real CPU. Nb: the first arg passed to + the function is always the ThreadId of the running + thread! So CLIENT_CALL0 actually requires a 1 arg + function, etc. */ + VG_USERREQ__CLIENT_CALL0 = 0x1101, + VG_USERREQ__CLIENT_CALL1 = 0x1102, + VG_USERREQ__CLIENT_CALL2 = 0x1103, + VG_USERREQ__CLIENT_CALL3 = 0x1104, + + /* Can be useful in regression testing suites -- eg. can + send Valgrind's output to /dev/null and still count + errors. */ + VG_USERREQ__COUNT_ERRORS = 0x1201, + + /* Allows the client program and/or gdbserver to execute a monitor + command. */ + VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, + + /* Allows the client program to change a dynamic command line + option. */ + VG_USERREQ__CLO_CHANGE = 0x1203, + + /* These are useful and can be interpreted by any tool that + tracks malloc() et al, by using vg_replace_malloc.c. */ + VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, + VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, + VG_USERREQ__FREELIKE_BLOCK = 0x1302, + /* Memory pool support. */ + VG_USERREQ__CREATE_MEMPOOL = 0x1303, + VG_USERREQ__DESTROY_MEMPOOL = 0x1304, + VG_USERREQ__MEMPOOL_ALLOC = 0x1305, + VG_USERREQ__MEMPOOL_FREE = 0x1306, + VG_USERREQ__MEMPOOL_TRIM = 0x1307, + VG_USERREQ__MOVE_MEMPOOL = 0x1308, + VG_USERREQ__MEMPOOL_CHANGE = 0x1309, + VG_USERREQ__MEMPOOL_EXISTS = 0x130a, + + /* Allow printfs to valgrind log. */ + /* The first two pass the va_list argument by value, which + assumes it is the same size as or smaller than a UWord, + which generally isn't the case. Hence are deprecated. + The second two pass the vargs by reference and so are + immune to this problem. */ + /* both :: char* fmt, va_list vargs (DEPRECATED) */ + VG_USERREQ__PRINTF = 0x1401, + VG_USERREQ__PRINTF_BACKTRACE = 0x1402, + /* both :: char* fmt, va_list* vargs */ + VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, + + /* Stack support. */ + VG_USERREQ__STACK_REGISTER = 0x1501, + VG_USERREQ__STACK_DEREGISTER = 0x1502, + VG_USERREQ__STACK_CHANGE = 0x1503, + + /* Wine support */ + VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, + + /* Querying of debug info. */ + VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, + + /* Disable/enable error reporting level. Takes a single + Word arg which is the delta to this thread's error + disablement indicator. Hence 1 disables or further + disables errors, and -1 moves back towards enablement. + Other values are not allowed. */ + VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801, + + /* Some requests used for Valgrind internal, such as + self-test or self-hosting. */ + /* Initialise IR injection */ + VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901, + /* Used by Inner Valgrind to inform Outer Valgrind where to + find the list of inner guest threads */ + VG_USERREQ__INNER_THREADS = 0x1902 + } Vg_ClientRequest; + +#if !defined(__GNUC__) +# define __extension__ /* */ +#endif + + +/* Returns the number of Valgrinds this code is running under. That + is, 0 if running natively, 1 if running under Valgrind, 2 if + running under Valgrind which is running under another Valgrind, + etc. */ +#define RUNNING_ON_VALGRIND \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ + VG_USERREQ__RUNNING_ON_VALGRIND, \ + 0, 0, 0, 0, 0) \ + + +/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + + _qzz_len - 1]. Useful if you are debugging a JITter or some such, + since it provides a way to make sure valgrind will retranslate the + invalidated area. Returns no value. */ +#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ + _qzz_addr, _qzz_len, 0, 0, 0) + +#define VALGRIND_INNER_THREADS(_qzz_addr) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS, \ + _qzz_addr, 0, 0, 0, 0) + + +/* These requests are for getting Valgrind itself to print something. + Possibly with a backtrace. This is a really ugly hack. The return value + is the number of characters printed, excluding the "**<pid>** " part at the + start and the backtrace (if present). */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) +/* Modern GCC will optimize the static routine out if unused, + and unused attribute will shut down warnings about it. */ +static int VALGRIND_PRINTF(const char *format, ...) + __attribute__((format(__printf__, 1, 2), __unused__)); +#endif +static int +#if defined(_MSC_VER) +__inline +#endif +VALGRIND_PRINTF(const char *format, ...) +{ +#if defined(NVALGRIND) + (void)format; + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) || defined(__MINGW64__) + uintptr_t _qzz_res; +#else + unsigned long _qzz_res; +#endif + va_list vargs; + va_start(vargs, format); +#if defined(_MSC_VER) || defined(__MINGW64__) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, + 0, 0, 0); +#endif + va_end(vargs); + return (int)_qzz_res; +#endif /* NVALGRIND */ +} + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) +static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) + __attribute__((format(__printf__, 1, 2), __unused__)); +#endif +static int +#if defined(_MSC_VER) +__inline +#endif +VALGRIND_PRINTF_BACKTRACE(const char *format, ...) +{ +#if defined(NVALGRIND) + (void)format; + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) || defined(__MINGW64__) + uintptr_t _qzz_res; +#else + unsigned long _qzz_res; +#endif + va_list vargs; + va_start(vargs, format); +#if defined(_MSC_VER) || defined(__MINGW64__) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, + 0, 0, 0); +#endif + va_end(vargs); + return (int)_qzz_res; +#endif /* NVALGRIND */ +} + + +/* These requests allow control to move from the simulated CPU to the + real CPU, calling an arbitrary function. + + Note that the current ThreadId is inserted as the first argument. + So this call: + + VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) + + requires f to have this signature: + + Word f(Word tid, Word arg1, Word arg2) + + where "Word" is a word-sized type. + + Note that these client requests are not entirely reliable. For example, + if you call a function with them that subsequently calls printf(), + there's a high chance Valgrind will crash. Generally, your prospects of + these working are made higher if the called function does not refer to + any global variables, and does not refer to any libc or other functions + (printf et al). Any kind of entanglement with libc or dynamic linking is + likely to have a bad outcome, for tricky reasons which we've grappled + with a lot in the past. +*/ +#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL0, \ + _qyy_fn, \ + 0, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL1, \ + _qyy_fn, \ + _qyy_arg1, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL2, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, 0, 0) + +#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL3, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, \ + _qyy_arg3, 0) + + +/* Counts the number of errors that have been recorded by a tool. Nb: + the tool must record the errors with VG_(maybe_record_error)() or + VG_(unique_error)() for them to be counted. */ +#define VALGRIND_COUNT_ERRORS \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + 0 /* default return */, \ + VG_USERREQ__COUNT_ERRORS, \ + 0, 0, 0, 0, 0) + +/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing + when heap blocks are allocated in order to give accurate results. This + happens automatically for the standard allocator functions such as + malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, + delete[], etc. + + But if your program uses a custom allocator, this doesn't automatically + happen, and Valgrind will not do as well. For example, if you allocate + superblocks with mmap() and then allocates chunks of the superblocks, all + Valgrind's observations will be at the mmap() level and it won't know that + the chunks should be considered separate entities. In Memcheck's case, + that means you probably won't get heap block overrun detection (because + there won't be redzones marked as unaddressable) and you definitely won't + get any leak detection. + + The following client requests allow a custom allocator to be annotated so + that it can be handled accurately by Valgrind. + + VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated + by a malloc()-like function. For Memcheck (an illustrative case), this + does two things: + + - It records that the block has been allocated. This means any addresses + within the block mentioned in error messages will be + identified as belonging to the block. It also means that if the block + isn't freed it will be detected by the leak checker. + + - It marks the block as being addressable and undefined (if 'is_zeroed' is + not set), or addressable and defined (if 'is_zeroed' is set). This + controls how accesses to the block by the program are handled. + + 'addr' is the start of the usable block (ie. after any + redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator + can apply redzones -- these are blocks of padding at the start and end of + each block. Adding redzones is recommended as it makes it much more likely + Valgrind will spot block overruns. `is_zeroed' indicates if the memory is + zeroed (or filled with another predictable value), as is the case for + calloc(). + + VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a + heap block -- that will be used by the client program -- is allocated. + It's best to put it at the outermost level of the allocator if possible; + for example, if you have a function my_alloc() which calls + internal_alloc(), and the client request is put inside internal_alloc(), + stack traces relating to the heap block will contain entries for both + my_alloc() and internal_alloc(), which is probably not what you want. + + For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out + custom blocks from within a heap block, B, that has been allocated with + malloc/calloc/new/etc, then block B will be *ignored* during leak-checking + -- the custom blocks will take precedence. + + VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For + Memcheck, it does two things: + + - It records that the block has been deallocated. This assumes that the + block was annotated as having been allocated via + VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. + + - It marks the block as being unaddressable. + + VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a + heap block is deallocated. + + VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For + Memcheck, it does four things: + + - It records that the size of a block has been changed. This assumes that + the block was annotated as having been allocated via + VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. + + - If the block shrunk, it marks the freed memory as being unaddressable. + + - If the block grew, it marks the new area as undefined and defines a red + zone past the end of the new block. + + - The V-bits of the overlap between the old and the new block are preserved. + + VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block + and before deallocation of the old block. + + In many cases, these three client requests will not be enough to get your + allocator working well with Memcheck. More specifically, if your allocator + writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call + will be necessary to mark the memory as addressable just before the zeroing + occurs, otherwise you'll get a lot of invalid write errors. For example, + you'll need to do this if your allocator recycles freed blocks, but it + zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). + Alternatively, if your allocator reuses freed blocks for allocator-internal + data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. + + Really, what's happening is a blurring of the lines between the client + program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the + memory should be considered unaddressable to the client program, but the + allocator knows more than the rest of the client program and so may be able + to safely access it. Extra client requests are necessary for Valgrind to + understand the distinction between the allocator and the rest of the + program. + + Ignored if addr == 0. +*/ +#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ + addr, sizeB, rzB, is_zeroed, 0) + +/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. + Ignored if addr == 0. +*/ +#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ + addr, oldSizeB, newSizeB, rzB, 0) + +/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. + Ignored if addr == 0. +*/ +#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ + addr, rzB, 0, 0, 0) + +/* Create a memory pool. */ +#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ + pool, rzB, is_zeroed, 0, 0) + +/* Create a memory pool with some flags specifying extended behaviour. + When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL. + + The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory + associated with the pool using VALGRIND_MEMPOOL_ALLOC will be used + by the application as superblocks to dole out MALLOC_LIKE blocks using + VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels" + pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC. + The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK. + Note that the association between the pool and the second level blocks + is implicit : second level blocks will be located inside first level + blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag + for such 2 levels pools, as otherwise valgrind will detect overlapping + memory blocks, and will abort execution (e.g. during leak search). + + Such a meta pool can also be marked as an 'auto free' pool using the flag + VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the + VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE + will automatically free the second level blocks that are contained + inside the first level block freed with VALGRIND_MEMPOOL_FREE. + In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls + to VALGRIND_FREELIKE_BLOCK for all the second level blocks included + in the first level block. + Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag + without the VALGRIND_MEMPOOL_METAPOOL flag. +*/ +#define VALGRIND_MEMPOOL_AUTO_FREE 1 +#define VALGRIND_MEMPOOL_METAPOOL 2 +#define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ + pool, rzB, is_zeroed, flags, 0) + +/* Destroy a memory pool. */ +#define VALGRIND_DESTROY_MEMPOOL(pool) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ + pool, 0, 0, 0, 0) + +/* Associate a piece of memory with a memory pool. */ +#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ + pool, addr, size, 0, 0) + +/* Disassociate a piece of memory from a memory pool. */ +#define VALGRIND_MEMPOOL_FREE(pool, addr) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ + pool, addr, 0, 0, 0) + +/* Disassociate any pieces outside a particular range. */ +#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ + pool, addr, size, 0, 0) + +/* Resize and/or move a piece associated with a memory pool. */ +#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ + poolA, poolB, 0, 0, 0) + +/* Resize and/or move a piece associated with a memory pool. */ +#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ + pool, addrA, addrB, size, 0) + +/* Return 1 if a mempool exists, else 0. */ +#define VALGRIND_MEMPOOL_EXISTS(pool) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__MEMPOOL_EXISTS, \ + pool, 0, 0, 0, 0) + +/* Mark a piece of memory as being a stack. Returns a stack id. + start is the lowest addressable stack byte, end is the highest + addressable stack byte. */ +#define VALGRIND_STACK_REGISTER(start, end) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__STACK_REGISTER, \ + start, end, 0, 0, 0) + +/* Unmark the piece of memory associated with a stack id as being a + stack. */ +#define VALGRIND_STACK_DEREGISTER(id) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ + id, 0, 0, 0, 0) + +/* Change the start and end address of the stack id. + start is the new lowest addressable stack byte, end is the new highest + addressable stack byte. */ +#define VALGRIND_STACK_CHANGE(id, start, end) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ + id, start, end, 0, 0) + +/* Load PDB debug info for Wine PE image_map. */ +#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ + fd, ptr, total_size, delta, 0) + +/* Map a code address to a source file name and line number. buf64 + must point to a 64-byte buffer in the caller's address space. The + result will be dumped in there and is guaranteed to be zero + terminated. If no info is found, the first byte is set to zero. */ +#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__MAP_IP_TO_SRCLOC, \ + addr, buf64, 0, 0, 0) + +/* Disable error reporting for this thread. Behaves in a stack like + way, so you can safely call this multiple times provided that + VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times + to re-enable reporting. The first call of this macro disables + reporting. Subsequent calls have no effect except to increase the + number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable + reporting. Child threads do not inherit this setting from their + parents -- they are always created with reporting enabled. */ +#define VALGRIND_DISABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + 1, 0, 0, 0, 0) + +/* Re-enable error reporting, as per comments on + VALGRIND_DISABLE_ERROR_REPORTING. */ +#define VALGRIND_ENABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + -1, 0, 0, 0, 0) + +/* Execute a monitor command from the client program. + If a connection is opened with GDB, the output will be sent + according to the output mode set for vgdb. + If no connection is opened, output will go to the log output. + Returns 1 if command not recognised, 0 otherwise. */ +#define VALGRIND_MONITOR_COMMAND(command) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \ + command, 0, 0, 0, 0) + + +/* Change the value of a dynamic command line option. + Note that unknown or not dynamically changeable options + will cause a warning message to be output. */ +#define VALGRIND_CLO_CHANGE(option) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CLO_CHANGE, \ + option, 0, 0, 0, 0) + + +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_win32 +#undef PLAT_amd64_win64 +#undef PLAT_x86_linux +#undef PLAT_amd64_linux +#undef PLAT_ppc32_linux +#undef PLAT_ppc64be_linux +#undef PLAT_ppc64le_linux +#undef PLAT_arm_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux +#undef PLAT_mips64_linux +#undef PLAT_nanomips_linux +#undef PLAT_x86_solaris +#undef PLAT_amd64_solaris + +#endif /* __VALGRIND_H */ diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c index 883ae5e9a..f79c767a9 100644 --- a/src/util/age_restriction.c +++ b/src/util/age_restriction.c @@ -671,11 +671,9 @@ TALER_age_restriction_from_secret ( ncp->commitment.num = num_pub; ncp->proof.num = num_priv; ncp->proof.keys = NULL; - ncp->commitment.keys = GNUNET_new_array ( num_pub, struct TALER_AgeCommitmentPublicKeyP); - if (0 < num_priv) ncp->proof.keys = GNUNET_new_array ( num_priv, diff --git a/src/util/config.c b/src/util/config.c index 7002a6d7c..e22207f77 100644 --- a/src/util/config.c +++ b/src/util/config.c @@ -271,20 +271,6 @@ parse_currencies_cb (void *cls, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cpc->cfg, section, - "DECIMAL_SEPARATOR", - &str)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - section, - "DECIMAL_SEPARATOR"); - cpc->failure = true; - return; - } - cspec->decimal_separator = str; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cpc->cfg, - section, "NAME", &str)) { @@ -487,8 +473,6 @@ TALER_CONFIG_currency_specs_to_json (const struct TALER_CurrencySpecification *cspec) { return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("decimal_separator", - cspec->decimal_separator), GNUNET_JSON_pack_string ("name", cspec->name), GNUNET_JSON_pack_string ("currency", @@ -515,7 +499,6 @@ TALER_CONFIG_free_currencies ( { struct TALER_CurrencySpecification *cspec = &cspecs[i]; - GNUNET_free (cspec->decimal_separator); GNUNET_free (cspec->name); json_decref (cspec->map_alt_unit_names); } diff --git a/src/util/conversion.c b/src/util/conversion.c index fdeffba40..504bb5ac0 100644 --- a/src/util/conversion.c +++ b/src/util/conversion.c @@ -150,7 +150,7 @@ read_cb (void *cls) ec->read_size = ns; } ret = GNUNET_DISK_file_read (ec->chld_stdout, - ec->read_buf, + ec->read_buf + ec->read_pos, ec->read_size - ec->read_pos); if (ret < 0) { @@ -255,6 +255,11 @@ child_done_cb (void *cls, json_error_t err; ec->cwh = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Conversion helper exited with status %d and code %llu after outputting %llu bytes of data\n", + (int) type, + (unsigned long long) exit_code, + (unsigned long long) ec->read_pos); if (NULL != ec->read_task) { GNUNET_SCHEDULER_cancel (ec->read_task); diff --git a/src/util/crypto.c b/src/util/crypto.c index caa5a1223..d8c6d7912 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -214,7 +214,7 @@ TALER_planchet_secret_to_transfer_priv ( void TALER_cs_withdraw_nonce_derive ( const struct TALER_PlanchetMasterSecretP *ps, - struct TALER_CsNonce *nonce) + struct GNUNET_CRYPTO_CsSessionNonce *nonce) { GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (nonce, @@ -232,7 +232,7 @@ void TALER_cs_refresh_nonce_derive ( const struct TALER_RefreshMasterSecretP *rms, uint32_t coin_num_salt, - struct TALER_CsNonce *nonce) + struct GNUNET_CRYPTO_CsSessionNonce *nonce) { uint32_t be_salt = htonl (coin_num_salt); @@ -250,10 +250,31 @@ TALER_cs_refresh_nonce_derive ( } +void +TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa, + struct TALER_RsaPubHashP *h_rsa) +{ + GNUNET_CRYPTO_rsa_public_key_hash (rsa, + &h_rsa->hash); + +} + + +void +TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs, + struct TALER_CsPubHashP *h_cs) +{ + GNUNET_CRYPTO_hash (cs, + sizeof(*cs), + &h_cs->hash); +} + + enum GNUNET_GenericReturnValue TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, const struct TALER_ExchangeWithdrawValues *alg_values, - const union TALER_DenominationBlindingKeyP *bks, + const union GNUNET_CRYPTO_BlindingSecretP *bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_AgeCommitmentHash *ach, struct TALER_CoinPubHashP *c_hash, @@ -262,12 +283,14 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, { struct TALER_CoinSpendPublicKeyP coin_pub; - GNUNET_assert (alg_values->cipher == dk->cipher); + GNUNET_assert (alg_values->blinding_inputs->cipher == + dk->bsign_pub_key->cipher); GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, &coin_pub.eddsa_pub); if (GNUNET_OK != TALER_denom_blind (dk, bks, + nonce, ach, &coin_pub, alg_values, @@ -294,15 +317,21 @@ enum GNUNET_GenericReturnValue TALER_planchet_to_coin ( const struct TALER_DenominationPublicKey *dk, const struct TALER_BlindedDenominationSignature *blind_sig, - const union TALER_DenominationBlindingKeyP *bks, + const union GNUNET_CRYPTO_BlindingSecretP *bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_AgeCommitmentHash *ach, const struct TALER_CoinPubHashP *c_hash, const struct TALER_ExchangeWithdrawValues *alg_values, struct TALER_FreshCoin *coin) { - if ( (dk->cipher != blind_sig->cipher) || - (dk->cipher != alg_values->cipher) ) + if (dk->bsign_pub_key->cipher != + blind_sig->blinded_sig->cipher) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (dk->bsign_pub_key->cipher != + alg_values->blinding_inputs->cipher) { GNUNET_break_op (0); return GNUNET_SYSERR; diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c index 5f7d3d6f9..dae0b6fc6 100644 --- a/src/util/crypto_helper_cs.c +++ b/src/util/crypto_helper_cs.c @@ -201,13 +201,18 @@ handle_mt_avail (struct TALER_CRYPTO_CsDenominationHelper *dh, } { - struct TALER_DenominationPublicKey denom_pub; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; struct TALER_CsPubHashP h_cs; - denom_pub.cipher = TALER_DENOMINATION_CS; - denom_pub.details.cs_public_key = kan->denom_pub; + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bsign_pub->cipher = GNUNET_CRYPTO_BSA_CS; + bsign_pub->rc = 1; + bsign_pub->details.cs_public_key = kan->denom_pub; - TALER_cs_pub_hash (&denom_pub.details.cs_public_key, &h_cs); + GNUNET_CRYPTO_hash (&bsign_pub->details.cs_public_key, + sizeof (bsign_pub->details.cs_public_key), + &bsign_pub->pub_key_hash); + h_cs.hash = bsign_pub->pub_key_hash; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received CS key %s (%s)\n", GNUNET_h2s (&h_cs.hash), @@ -222,7 +227,7 @@ handle_mt_avail (struct TALER_CRYPTO_CsDenominationHelper *dh, &kan->secm_sig)) { GNUNET_break_op (0); - TALER_denom_pub_free (&denom_pub); + GNUNET_CRYPTO_blind_sign_pub_decref (bsign_pub); return GNUNET_SYSERR; } dh->dkc (dh->dkc_cls, @@ -230,10 +235,10 @@ handle_mt_avail (struct TALER_CRYPTO_CsDenominationHelper *dh, GNUNET_TIME_timestamp_ntoh (kan->anchor_time), GNUNET_TIME_relative_ntoh (kan->duration_withdraw), &h_cs, - &denom_pub, + bsign_pub, &kan->secm_pub, &kan->secm_sig); - TALER_denom_pub_free (&denom_pub); + GNUNET_CRYPTO_blind_sign_pub_decref (bsign_pub); } return GNUNET_OK; } @@ -387,10 +392,10 @@ TALER_CRYPTO_helper_cs_sign ( { enum TALER_ErrorCode ec = TALER_EC_INVALID; const struct TALER_CsPubHashP *h_cs = req->h_cs; - const struct TALER_BlindedCsPlanchet *blinded_planchet = - req->blinded_planchet; - bs->cipher = TALER_DENOMINATION_INVALID; + memset (bs, + 0, + sizeof (*bs)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting signature process\n"); if (GNUNET_OK != @@ -412,7 +417,7 @@ TALER_CRYPTO_helper_cs_sign ( sr->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN); sr->for_melt = htonl (for_melt ? 1 : 0); sr->h_cs = *h_cs; - sr->planchet = *blinded_planchet; + sr->message = *req->blinded_planchet; if (GNUNET_OK != TALER_crypto_helper_send_all (dh->sock, buf, @@ -495,13 +500,18 @@ more: { const struct TALER_CRYPTO_SignResponse *sr = (const struct TALER_CRYPTO_SignResponse *) buf; + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received signature\n"); ec = TALER_EC_NONE; finished = true; - bs->cipher = TALER_DENOMINATION_CS; - bs->details.blinded_cs_answer = sr->cs_answer; + blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blinded_sig->cipher = GNUNET_CRYPTO_BSA_CS; + blinded_sig->rc = 1; + blinded_sig->details.blinded_cs_answer.b = ntohl (sr->b); + blinded_sig->details.blinded_cs_answer.s_scalar = sr->cs_answer; + bs->blinded_sig = blinded_sig; break; } case TALER_HELPER_CS_MT_RES_SIGN_FAILURE: @@ -611,11 +621,11 @@ enum TALER_ErrorCode TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh, const struct TALER_CRYPTO_CsDeriveRequest *cdr, bool for_melt, - struct TALER_DenominationCSPublicRPairP *crp) + struct GNUNET_CRYPTO_CSPublicRPairP *crp) { enum TALER_ErrorCode ec = TALER_EC_INVALID; const struct TALER_CsPubHashP *h_cs = cdr->h_cs; - const struct TALER_CsNonce *nonce = cdr->nonce; + const struct GNUNET_CRYPTO_CsSessionNonce *nonce = cdr->nonce; memset (crp, 0, @@ -795,10 +805,10 @@ more: enum TALER_ErrorCode TALER_CRYPTO_helper_cs_batch_sign ( struct TALER_CRYPTO_CsDenominationHelper *dh, - const struct TALER_CRYPTO_CsSignRequest *reqs, unsigned int reqs_length, + const struct TALER_CRYPTO_CsSignRequest reqs[static reqs_length], bool for_melt, - struct TALER_BlindedDenominationSignature *bss) + struct TALER_BlindedDenominationSignature bss[static reqs_length]) { enum TALER_ErrorCode ec = TALER_EC_INVALID; unsigned int rpos; @@ -854,7 +864,7 @@ TALER_CRYPTO_helper_cs_batch_sign ( csm->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN); csm->for_melt = htonl (for_melt ? 1 : 0); csm->h_cs = *csr->h_cs; - csm->planchet = *csr->blinded_planchet; + csm->message = *csr->blinded_planchet; wbuf += sizeof (*csm); } GNUNET_assert (wbuf == &obuf[mlen]); @@ -945,12 +955,17 @@ more: { const struct TALER_CRYPTO_SignResponse *sr = (const struct TALER_CRYPTO_SignResponse *) buf; - + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u signature\n", wpos); - bss[wpos].cipher = TALER_DENOMINATION_CS; - bss[wpos].details.blinded_cs_answer = sr->cs_answer; + blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blinded_sig->cipher = GNUNET_CRYPTO_BSA_CS; + blinded_sig->rc = 1; + blinded_sig->details.blinded_cs_answer.b = ntohl (sr->b); + blinded_sig->details.blinded_cs_answer.s_scalar = sr->cs_answer; + + bss[wpos].blinded_sig = blinded_sig; wpos++; if (wpos == rend) { @@ -1040,10 +1055,10 @@ more: enum TALER_ErrorCode TALER_CRYPTO_helper_cs_r_batch_derive ( struct TALER_CRYPTO_CsDenominationHelper *dh, - const struct TALER_CRYPTO_CsDeriveRequest *cdrs, unsigned int cdrs_length, + const struct TALER_CRYPTO_CsDeriveRequest cdrs[static cdrs_length], bool for_melt, - struct TALER_DenominationCSPublicRPairP *crps) + struct GNUNET_CRYPTO_CSPublicRPairP crps[static cdrs_length]) { enum TALER_ErrorCode ec = TALER_EC_INVALID; unsigned int rpos; diff --git a/src/util/crypto_helper_rsa.c b/src/util/crypto_helper_rsa.c index 4098a846b..58ed5a375 100644 --- a/src/util/crypto_helper_rsa.c +++ b/src/util/crypto_helper_rsa.c @@ -203,23 +203,27 @@ handle_mt_avail (struct TALER_CRYPTO_RsaDenominationHelper *dh, } { - struct TALER_DenominationPublicKey denom_pub; + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub; struct TALER_RsaPubHashP h_rsa; - denom_pub.cipher = TALER_DENOMINATION_RSA; - denom_pub.details.rsa_public_key + bs_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bs_pub->cipher = GNUNET_CRYPTO_BSA_RSA; + bs_pub->details.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf, ntohs (kan->pub_size)); - if (NULL == denom_pub.details.rsa_public_key) + if (NULL == bs_pub->details.rsa_public_key) { GNUNET_break_op (0); + GNUNET_free (bs_pub); return GNUNET_SYSERR; } - GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.details.rsa_public_key, - &h_rsa.hash); + bs_pub->rc = 1; + GNUNET_CRYPTO_rsa_public_key_hash (bs_pub->details.rsa_public_key, + &bs_pub->pub_key_hash); + h_rsa.hash = bs_pub->pub_key_hash; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received RSA key %s (%s)\n", - GNUNET_h2s (&h_rsa.hash), + GNUNET_h2s (&bs_pub->pub_key_hash), section_name); if (GNUNET_OK != TALER_exchange_secmod_rsa_verify ( @@ -231,7 +235,7 @@ handle_mt_avail (struct TALER_CRYPTO_RsaDenominationHelper *dh, &kan->secm_sig)) { GNUNET_break_op (0); - TALER_denom_pub_free (&denom_pub); + GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub); return GNUNET_SYSERR; } dh->dkc (dh->dkc_cls, @@ -239,10 +243,10 @@ handle_mt_avail (struct TALER_CRYPTO_RsaDenominationHelper *dh, GNUNET_TIME_timestamp_ntoh (kan->anchor_time), GNUNET_TIME_relative_ntoh (kan->duration_withdraw), &h_rsa, - &denom_pub, + bs_pub, &kan->secm_pub, &kan->secm_sig); - TALER_denom_pub_free (&denom_pub); + GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub); } return GNUNET_OK; } @@ -395,7 +399,9 @@ TALER_CRYPTO_helper_rsa_sign ( { enum TALER_ErrorCode ec = TALER_EC_INVALID; - bs->cipher = TALER_DENOMINATION_INVALID; + memset (bs, + 0, + sizeof (*bs)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting signature process\n"); if (GNUNET_OK != @@ -503,6 +509,7 @@ more: const struct TALER_CRYPTO_SignResponse *sr = (const struct TALER_CRYPTO_SignResponse *) buf; struct GNUNET_CRYPTO_RsaSignature *rsa_signature; + struct GNUNET_CRYPTO_BlindedSignature *blind_sig; rsa_signature = GNUNET_CRYPTO_rsa_signature_decode ( &sr[1], @@ -518,8 +525,11 @@ more: "Received signature\n"); ec = TALER_EC_NONE; finished = true; - bs->cipher = TALER_DENOMINATION_RSA; - bs->details.blinded_rsa_signature = rsa_signature; + blind_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blind_sig->cipher = GNUNET_CRYPTO_BSA_RSA; + blind_sig->rc = 1; + blind_sig->details.blinded_rsa_signature = rsa_signature; + bs->blinded_sig = blind_sig; break; } case TALER_HELPER_RSA_MT_RES_SIGN_FAILURE: @@ -597,9 +607,9 @@ end: enum TALER_ErrorCode TALER_CRYPTO_helper_rsa_batch_sign ( struct TALER_CRYPTO_RsaDenominationHelper *dh, - const struct TALER_CRYPTO_RsaSignRequest *rsrs, unsigned int rsrs_length, - struct TALER_BlindedDenominationSignature *bss) + const struct TALER_CRYPTO_RsaSignRequest rsrs[static rsrs_length], + struct TALER_BlindedDenominationSignature bss[static rsrs_length]) { enum TALER_ErrorCode ec = TALER_EC_INVALID; unsigned int rpos; @@ -750,6 +760,7 @@ more: const struct TALER_CRYPTO_SignResponse *sr = (const struct TALER_CRYPTO_SignResponse *) buf; struct GNUNET_CRYPTO_RsaSignature *rsa_signature; + struct GNUNET_CRYPTO_BlindedSignature *blind_sig; rsa_signature = GNUNET_CRYPTO_rsa_signature_decode ( &sr[1], @@ -763,8 +774,11 @@ more: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u signature\n", wpos); - bss[wpos].cipher = TALER_DENOMINATION_RSA; - bss[wpos].details.blinded_rsa_signature = rsa_signature; + blind_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blind_sig->cipher = GNUNET_CRYPTO_BSA_RSA; + blind_sig->rc = 1; + blind_sig->details.blinded_rsa_signature = rsa_signature; + bss[wpos].blinded_sig = blind_sig; wpos++; if (wpos == rend) { diff --git a/src/util/currencies.conf b/src/util/currencies.conf index 3341a9a72..539804fc2 100644 --- a/src/util/currencies.conf +++ b/src/util/currencies.conf @@ -2,7 +2,6 @@ ENABLED = YES name = "Euro" code = "EUR" -decimal_separator = "," fractional_input_digits = 2 fractional_normal_digits = 2 fractional_trailing_zero_digits = 2 @@ -13,7 +12,6 @@ alt_unit_names = {"0":"€"} ENABLED = YES name = "Swiss Francs" code = "CHF" -decimal_separator = "." fractional_input_digits = 2 fractional_normal_digits = 2 fractional_trailing_zero_digits = 2 @@ -24,7 +22,6 @@ alt_unit_names = {"0":"Fr.","-2":"Rp."} ENABLED = NO name = "Hungarian Forint" code = "HUF" -decimal_separator = "," fractional_input_digits = 0 fractional_normal_digits = 0 fractional_trailing_zero_digits = 0 @@ -35,7 +32,6 @@ alt_unit_names = {"0":"Ft"} ENABLED = NO name = "US Dollar" code = "USD" -decimal_separator = "." fractional_input_digits = 2 fractional_normal_digits = 2 fractional_trailing_zero_digits = 2 @@ -46,7 +42,6 @@ alt_unit_names = {"0":"$"} ENABLED = YES name = "Kudos (Taler Demonstrator)" code = "KUDOS" -decimal_separator = "," fractional_input_digits = 2 fractional_normal_digits = 2 fractional_trailing_zero_digits = 2 @@ -57,7 +52,6 @@ alt_unit_names = {"0":"ク"} ENABLED = YES name = "Test-kudos (Taler Demonstrator)" code = "TESTKUDOS" -decimal_separator = "." fractional_input_digits = 2 fractional_normal_digits = 2 fractional_trailing_zero_digits = 2 @@ -68,7 +62,6 @@ alt_unit_names = {"0":"テ","3":"kテ","-3":"mテ"} ENABLED = NO name = "Japanese Yen" code = "JPY" -decimal_separator = "." fractional_input_digits = 2 fractional_normal_digits = 0 fractional_trailing_zero_digits = 2 @@ -79,7 +72,6 @@ alt_unit_names = {"0":"¥"} ENABLED = NO name = "Bitcoin (Mainnet)" code = "BITCOINBTC" -decimal_separator = "." fractional_input_digits = 8 fractional_normal_digits = 3 fractional_trailing_zero_digits = 0 @@ -90,10 +82,8 @@ alt_unit_names = {"0":"BTC","-3":"mBTC"} ENABLED = NO name = "WAI-ETHER (Ethereum)" code = "EthereumWAI" -decimal_separator = "." fractional_input_digits = 0 fractional_normal_digits = 0 fractional_trailing_zero_digits = 0 is_currency_name_leading = NO alt_unit_names = {"0":"WAI","3":"KWAI","6":"MWAI","9":"GWAI","12":"Szabo","15":"Finney","18":"Ether","21":"KEther","24":"MEther"} - diff --git a/src/util/denom.c b/src/util/denom.c index c1c3cdf5a..928c46328 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021, 2022 Taler Systems SA + Copyright (C) 2021, 2022, 2023 Taler Systems SA TALER 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 @@ -25,60 +25,27 @@ enum GNUNET_GenericReturnValue TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv, struct TALER_DenominationPublicKey *denom_pub, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, ...) { - memset (denom_priv, - 0, - sizeof (*denom_priv)); + enum GNUNET_GenericReturnValue ret; + va_list ap; + memset (denom_pub, 0, sizeof (*denom_pub)); - - switch (cipher) - { - case TALER_DENOMINATION_INVALID: - GNUNET_break (0); - return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: - { - va_list ap; - unsigned int bits; - - va_start (ap, cipher); - bits = va_arg (ap, unsigned int); - va_end (ap); - if (bits < 512) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - denom_priv->details.rsa_private_key - = GNUNET_CRYPTO_rsa_private_key_create (bits); - } - if (NULL == denom_priv->details.rsa_private_key) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - denom_pub->details.rsa_public_key - = GNUNET_CRYPTO_rsa_private_key_get_public ( - denom_priv->details.rsa_private_key); - denom_priv->cipher = TALER_DENOMINATION_RSA; - denom_pub->cipher = TALER_DENOMINATION_RSA; - return GNUNET_OK; - case TALER_DENOMINATION_CS: - GNUNET_CRYPTO_cs_private_key_generate (&denom_priv->details.cs_private_key); - GNUNET_CRYPTO_cs_private_key_get_public ( - &denom_priv->details.cs_private_key, - &denom_pub->details.cs_public_key); - denom_priv->cipher = TALER_DENOMINATION_CS; - denom_pub->cipher = TALER_DENOMINATION_CS; - return GNUNET_OK; - default: - GNUNET_break (0); - } - return GNUNET_SYSERR; + memset (denom_priv, + 0, + sizeof (*denom_priv)); + va_start (ap, + cipher); + ret = GNUNET_CRYPTO_blind_sign_keys_create_va ( + &denom_priv->bsign_priv_key, + &denom_pub->bsign_pub_key, + cipher, + ap); + va_end (ap); + return ret; } @@ -88,57 +55,13 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, bool for_melt, const struct TALER_BlindedPlanchet *blinded_planchet) { - memset (denom_sig, - 0, - sizeof (*denom_sig)); - if (blinded_planchet->cipher != denom_priv->cipher) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - switch (denom_priv->cipher) - { - case TALER_DENOMINATION_INVALID: - GNUNET_break (0); + denom_sig->blinded_sig + = GNUNET_CRYPTO_blind_sign (denom_priv->bsign_priv_key, + for_melt ? "rm" : "rw", + blinded_planchet->blinded_message); + if (NULL == denom_sig->blinded_sig) return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: - denom_sig->details.blinded_rsa_signature - = GNUNET_CRYPTO_rsa_sign_blinded ( - denom_priv->details.rsa_private_key, - blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size); - if (NULL == denom_sig->details.blinded_rsa_signature) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - denom_sig->cipher = TALER_DENOMINATION_RSA; - return GNUNET_OK; - case TALER_DENOMINATION_CS: - { - struct GNUNET_CRYPTO_CsRSecret r[2]; - - GNUNET_CRYPTO_cs_r_derive ( - &blinded_planchet->details.cs_blinded_planchet.nonce.nonce, - for_melt ? "rm" : "rw", - &denom_priv->details.cs_private_key, - r); - denom_sig->details.blinded_cs_answer.b = - GNUNET_CRYPTO_cs_sign_derive (&denom_priv->details.cs_private_key, - r, - blinded_planchet->details. - cs_blinded_planchet.c, - &blinded_planchet->details. - cs_blinded_planchet.nonce.nonce, - &denom_sig->details.blinded_cs_answer. - s_scalar); - denom_sig->cipher = TALER_DENOMINATION_CS; - } - return GNUNET_OK; - default: - GNUNET_break (0); - } - return GNUNET_SYSERR; + return GNUNET_OK; } @@ -146,82 +69,24 @@ enum GNUNET_GenericReturnValue TALER_denom_sig_unblind ( struct TALER_DenominationSignature *denom_sig, const struct TALER_BlindedDenominationSignature *bdenom_sig, - const union TALER_DenominationBlindingKeyP *bks, + const union GNUNET_CRYPTO_BlindingSecretP *bks, const struct TALER_CoinPubHashP *c_hash, const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_DenominationPublicKey *denom_pub) { - if (bdenom_sig->cipher != denom_pub->cipher) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - switch (denom_pub->cipher) + denom_sig->unblinded_sig + = GNUNET_CRYPTO_blind_sig_unblind (bdenom_sig->blinded_sig, + bks, + c_hash, + sizeof (*c_hash), + alg_values->blinding_inputs, + denom_pub->bsign_pub_key); + if (NULL == denom_sig->unblinded_sig) { - case TALER_DENOMINATION_INVALID: - GNUNET_break (0); + GNUNET_break_op (0); return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: - denom_sig->details.rsa_signature - = GNUNET_CRYPTO_rsa_unblind ( - bdenom_sig->details.blinded_rsa_signature, - &bks->rsa_bks, - denom_pub->details.rsa_public_key); - if (NULL == denom_sig->details.rsa_signature) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - denom_sig->cipher = TALER_DENOMINATION_RSA; - return GNUNET_OK; - case TALER_DENOMINATION_CS: - { - struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; - struct GNUNET_CRYPTO_CsC c[2]; - struct TALER_DenominationCSPublicRPairP r_pub_blind; - - GNUNET_CRYPTO_cs_blinding_secrets_derive (&bks->nonce, - bs); - GNUNET_CRYPTO_cs_calc_blinded_c ( - bs, - alg_values->details.cs_values.r_pub, - &denom_pub->details.cs_public_key, - &c_hash->hash, - sizeof(struct GNUNET_HashCode), - c, - r_pub_blind.r_pub); - denom_sig->details.cs_signature.r_point - = r_pub_blind.r_pub[bdenom_sig->details.blinded_cs_answer.b]; - GNUNET_CRYPTO_cs_unblind (&bdenom_sig->details.blinded_cs_answer.s_scalar, - &bs[bdenom_sig->details.blinded_cs_answer.b], - &denom_sig->details.cs_signature.s_scalar); - denom_sig->cipher = TALER_DENOMINATION_CS; - return GNUNET_OK; - } - default: - GNUNET_break (0); } - return GNUNET_SYSERR; -} - - -void -TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa, - struct TALER_RsaPubHashP *h_rsa) -{ - GNUNET_CRYPTO_rsa_public_key_hash (rsa, - &h_rsa->hash); - -} - - -void -TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs, - struct TALER_CsPubHashP *h_cs) -{ - GNUNET_CRYPTO_hash (cs, - sizeof(*cs), - &h_cs->hash); + return GNUNET_OK; } @@ -229,9 +94,11 @@ void TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, struct TALER_DenominationHashP *denom_hash) { + struct GNUNET_CRYPTO_BlindSignPublicKey *bsp + = denom_pub->bsign_pub_key; uint32_t opt[2] = { htonl (denom_pub->age_mask.bits), - htonl ((uint32_t) denom_pub->cipher) + htonl ((uint32_t) bsp->cipher) }; struct GNUNET_HashContext *hc; @@ -239,15 +106,15 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, GNUNET_CRYPTO_hash_context_read (hc, opt, sizeof (opt)); - switch (denom_pub->cipher) + switch (bsp->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: { void *buf; size_t blen; blen = GNUNET_CRYPTO_rsa_public_key_encode ( - denom_pub->details.rsa_public_key, + bsp->details.rsa_public_key, &buf); GNUNET_CRYPTO_hash_context_read (hc, buf, @@ -255,10 +122,10 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, GNUNET_free (buf); } break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_CRYPTO_hash_context_read (hc, - &denom_pub->details.cs_public_key, - sizeof(denom_pub->details.cs_public_key)); + &bsp->details.cs_public_key, + sizeof(bsp->details.cs_public_key)); break; default: GNUNET_assert (0); @@ -268,37 +135,24 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, } -void -TALER_denom_priv_to_pub (const struct TALER_DenominationPrivateKey *denom_priv, - const struct TALER_AgeMask age_mask, - struct TALER_DenominationPublicKey *denom_pub) +const struct TALER_ExchangeWithdrawValues * +TALER_denom_ewv_rsa_singleton () { - switch (denom_priv->cipher) - { - case TALER_DENOMINATION_RSA: - denom_pub->cipher = TALER_DENOMINATION_RSA; - denom_pub->age_mask = age_mask; - denom_pub->details.rsa_public_key - = GNUNET_CRYPTO_rsa_private_key_get_public ( - denom_priv->details.rsa_private_key); - return; - case TALER_DENOMINATION_CS: - denom_pub->cipher = TALER_DENOMINATION_CS; - denom_pub->age_mask = age_mask; - GNUNET_CRYPTO_cs_private_key_get_public ( - &denom_priv->details.cs_private_key, - &denom_pub->details.cs_public_key); - return; - default: - GNUNET_assert (0); - } + static struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_RSA + }; + static struct TALER_ExchangeWithdrawValues alg_values = { + .blinding_inputs = &bi + }; + return &alg_values; } enum GNUNET_GenericReturnValue TALER_denom_blind ( const struct TALER_DenominationPublicKey *dk, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const struct TALER_AgeCommitmentHash *ach, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_ExchangeWithdrawValues *alg_values, @@ -308,44 +162,16 @@ TALER_denom_blind ( TALER_coin_pub_hash (coin_pub, ach, c_hash); - switch (dk->cipher) - { - case TALER_DENOMINATION_RSA: - blinded_planchet->cipher = dk->cipher; - if (GNUNET_YES != - GNUNET_CRYPTO_rsa_blind ( - &c_hash->hash, - &coin_bks->rsa_bks, - dk->details.rsa_public_key, - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; - case TALER_DENOMINATION_CS: - { - struct TALER_DenominationCSPublicRPairP blinded_r_pub; - struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; - - blinded_planchet->cipher = TALER_DENOMINATION_CS; - GNUNET_CRYPTO_cs_blinding_secrets_derive (&coin_bks->nonce, - bs); - GNUNET_CRYPTO_cs_calc_blinded_c ( - bs, - alg_values->details.cs_values.r_pub, - &dk->details.cs_public_key, - c_hash, - sizeof(*c_hash), - blinded_planchet->details.cs_blinded_planchet.c, - blinded_r_pub.r_pub); - return GNUNET_OK; - } - default: - GNUNET_break (0); + blinded_planchet->blinded_message + = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key, + coin_bks, + nonce, + c_hash, + sizeof (*c_hash), + alg_values->blinding_inputs); + if (NULL == blinded_planchet->blinded_message) return GNUNET_SYSERR; - } + return GNUNET_OK; } @@ -354,64 +180,20 @@ TALER_denom_pub_verify (const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationSignature *denom_sig, const struct TALER_CoinPubHashP *c_hash) { - if (denom_pub->cipher != denom_sig->cipher) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - switch (denom_pub->cipher) - { - case TALER_DENOMINATION_INVALID: - GNUNET_break (0); - return GNUNET_NO; - case TALER_DENOMINATION_RSA: - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (&c_hash->hash, - denom_sig->details.rsa_signature, - denom_pub->details.rsa_public_key)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Coin signature is invalid\n"); - return GNUNET_NO; - } - return GNUNET_YES; - case TALER_DENOMINATION_CS: - if (GNUNET_OK != - GNUNET_CRYPTO_cs_verify (&denom_sig->details.cs_signature, - &denom_pub->details.cs_public_key, - &c_hash->hash, - sizeof(struct GNUNET_HashCode))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Coin signature is invalid\n"); - return GNUNET_NO; - } - return GNUNET_YES; - default: - GNUNET_assert (0); - } + return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key, + denom_sig->unblinded_sig, + c_hash, + sizeof (*c_hash)); } void TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub) { - switch (denom_pub->cipher) + if (NULL != denom_pub->bsign_pub_key) { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - if (NULL != denom_pub->details.rsa_public_key) - { - GNUNET_CRYPTO_rsa_public_key_free (denom_pub->details.rsa_public_key); - denom_pub->details.rsa_public_key = NULL; - } - denom_pub->cipher = TALER_DENOMINATION_INVALID; - return; - case TALER_DENOMINATION_CS: - return; - default: - GNUNET_assert (0); + GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key); + denom_pub->bsign_pub_key = NULL; } } @@ -419,22 +201,10 @@ TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub) void TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv) { - switch (denom_priv->cipher) + if (NULL != denom_priv->bsign_priv_key) { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - if (NULL != denom_priv->details.rsa_private_key) - { - GNUNET_CRYPTO_rsa_private_key_free (denom_priv->details.rsa_private_key); - denom_priv->details.rsa_private_key = NULL; - } - denom_priv->cipher = TALER_DENOMINATION_INVALID; - return; - case TALER_DENOMINATION_CS: - return; - default: - GNUNET_assert (0); + GNUNET_CRYPTO_blind_sign_priv_decref (denom_priv->bsign_priv_key); + denom_priv->bsign_priv_key = NULL; } } @@ -442,22 +212,10 @@ TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv) void TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig) { - switch (denom_sig->cipher) + if (NULL != denom_sig->unblinded_sig) { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - if (NULL != denom_sig->details.rsa_signature) - { - GNUNET_CRYPTO_rsa_signature_free (denom_sig->details.rsa_signature); - denom_sig->details.rsa_signature = NULL; - } - denom_sig->cipher = TALER_DENOMINATION_INVALID; - return; - case TALER_DENOMINATION_CS: - return; - default: - GNUNET_assert (0); + GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig); + denom_sig->unblinded_sig = NULL; } } @@ -466,44 +224,54 @@ void TALER_blinded_denom_sig_free ( struct TALER_BlindedDenominationSignature *denom_sig) { - switch (denom_sig->cipher) + if (NULL != denom_sig->blinded_sig) { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - if (NULL != denom_sig->details.blinded_rsa_signature) - { - GNUNET_CRYPTO_rsa_signature_free ( - denom_sig->details.blinded_rsa_signature); - denom_sig->details.blinded_rsa_signature = NULL; - } - denom_sig->cipher = TALER_DENOMINATION_INVALID; + GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig); + denom_sig->blinded_sig = NULL; + } +} + + +void +TALER_denom_ewv_free (struct TALER_ExchangeWithdrawValues *ewv) +{ + if (ewv == TALER_denom_ewv_rsa_singleton ()) return; - case TALER_DENOMINATION_CS: + if (ewv->blinding_inputs == + TALER_denom_ewv_rsa_singleton ()->blinding_inputs) + { + ewv->blinding_inputs = NULL; return; - default: - GNUNET_assert (0); + } + if (NULL != ewv->blinding_inputs) + { + GNUNET_CRYPTO_blinding_input_values_decref (ewv->blinding_inputs); + ewv->blinding_inputs = NULL; } } void -TALER_denom_pub_deep_copy (struct TALER_DenominationPublicKey *denom_dst, - const struct TALER_DenominationPublicKey *denom_src) +TALER_denom_ewv_deep_copy (struct TALER_ExchangeWithdrawValues *bi_dst, + const struct TALER_ExchangeWithdrawValues *bi_src) { - *denom_dst = *denom_src; /* shallow copy */ - switch (denom_src->cipher) + if (bi_src == TALER_denom_ewv_rsa_singleton ()) { - case TALER_DENOMINATION_RSA: - denom_dst->details.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_dup ( - denom_src->details.rsa_public_key); - return; - case TALER_DENOMINATION_CS: + *bi_dst = *bi_src; return; - default: - GNUNET_assert (0); } + bi_dst->blinding_inputs + = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs); +} + + +void +TALER_denom_pub_deep_copy (struct TALER_DenominationPublicKey *denom_dst, + const struct TALER_DenominationPublicKey *denom_src) +{ + denom_dst->age_mask = denom_src->age_mask; + denom_dst->bsign_pub_key + = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key); } @@ -511,21 +279,8 @@ void TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst, const struct TALER_DenominationSignature *denom_src) { - *denom_dst = *denom_src; /* shallow copy */ - switch (denom_src->cipher) - { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - denom_dst->details.rsa_signature - = GNUNET_CRYPTO_rsa_signature_dup ( - denom_src->details.rsa_signature); - return; - case TALER_DENOMINATION_CS: - return; - default: - GNUNET_assert (0); - } + denom_dst->unblinded_sig + = GNUNET_CRYPTO_ub_sig_incref (denom_src->unblinded_sig); } @@ -534,21 +289,8 @@ TALER_blinded_denom_sig_deep_copy ( struct TALER_BlindedDenominationSignature *denom_dst, const struct TALER_BlindedDenominationSignature *denom_src) { - *denom_dst = *denom_src; /* shallow copy */ - switch (denom_src->cipher) - { - case TALER_DENOMINATION_INVALID: - return; - case TALER_DENOMINATION_RSA: - denom_dst->details.blinded_rsa_signature - = GNUNET_CRYPTO_rsa_signature_dup ( - denom_src->details.blinded_rsa_signature); - return; - case TALER_DENOMINATION_CS: - return; - default: - GNUNET_assert (0); - } + denom_dst->blinded_sig + = GNUNET_CRYPTO_blind_sig_incref (denom_src->blinded_sig); } @@ -556,24 +298,14 @@ int TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1, const struct TALER_DenominationPublicKey *denom2) { - if (denom1->cipher != denom2->cipher) - return (denom1->cipher > denom2->cipher) ? 1 : -1; + if (denom1->bsign_pub_key->cipher != + denom2->bsign_pub_key->cipher) + return (denom1->bsign_pub_key->cipher > + denom2->bsign_pub_key->cipher) ? 1 : -1; if (denom1->age_mask.bits != denom2->age_mask.bits) return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1; - switch (denom1->cipher) - { - case TALER_DENOMINATION_INVALID: - return 0; - case TALER_DENOMINATION_RSA: - return GNUNET_CRYPTO_rsa_public_key_cmp (denom1->details.rsa_public_key, - denom2->details.rsa_public_key); - case TALER_DENOMINATION_CS: - return GNUNET_memcmp (&denom1->details.cs_public_key, - &denom2->details.cs_public_key); - default: - GNUNET_assert (0); - } - return -2; + return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key, + denom2->bsign_pub_key); } @@ -581,22 +313,8 @@ int TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1, const struct TALER_DenominationSignature *sig2) { - if (sig1->cipher != sig2->cipher) - return (sig1->cipher > sig2->cipher) ? 1 : -1; - switch (sig1->cipher) - { - case TALER_DENOMINATION_INVALID: - return 0; - case TALER_DENOMINATION_RSA: - return GNUNET_CRYPTO_rsa_signature_cmp (sig1->details.rsa_signature, - sig2->details.rsa_signature); - case TALER_DENOMINATION_CS: - return GNUNET_memcmp (&sig1->details.cs_signature, - &sig2->details.cs_signature); - default: - GNUNET_assert (0); - } - return -2; + return GNUNET_CRYPTO_ub_sig_cmp (sig1->unblinded_sig, + sig1->unblinded_sig); } @@ -605,27 +323,8 @@ TALER_blinded_planchet_cmp ( const struct TALER_BlindedPlanchet *bp1, const struct TALER_BlindedPlanchet *bp2) { - if (bp1->cipher != bp2->cipher) - return (bp1->cipher > bp2->cipher) ? 1 : -1; - switch (bp1->cipher) - { - case TALER_DENOMINATION_INVALID: - return 0; - case TALER_DENOMINATION_RSA: - if (bp1->details.rsa_blinded_planchet.blinded_msg_size != - bp2->details.rsa_blinded_planchet.blinded_msg_size) - return (bp1->details.rsa_blinded_planchet.blinded_msg_size > - bp2->details.rsa_blinded_planchet.blinded_msg_size) ? 1 : -1; - return memcmp (bp1->details.rsa_blinded_planchet.blinded_msg, - bp2->details.rsa_blinded_planchet.blinded_msg, - bp1->details.rsa_blinded_planchet.blinded_msg_size); - case TALER_DENOMINATION_CS: - return GNUNET_memcmp (&bp1->details.cs_blinded_planchet, - &bp2->details.cs_blinded_planchet); - default: - GNUNET_assert (0); - } - return -2; + return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message, + bp2->blinded_message); } @@ -634,22 +333,8 @@ TALER_blinded_denom_sig_cmp ( const struct TALER_BlindedDenominationSignature *sig1, const struct TALER_BlindedDenominationSignature *sig2) { - if (sig1->cipher != sig2->cipher) - return (sig1->cipher > sig2->cipher) ? 1 : -1; - switch (sig1->cipher) - { - case TALER_DENOMINATION_INVALID: - return 0; - case TALER_DENOMINATION_RSA: - return GNUNET_CRYPTO_rsa_signature_cmp (sig1->details.blinded_rsa_signature, - sig2->details.blinded_rsa_signature); - case TALER_DENOMINATION_CS: - return GNUNET_memcmp (&sig1->details.blinded_cs_answer, - &sig2->details.blinded_cs_answer); - default: - GNUNET_assert (0); - } - return -2; + return GNUNET_CRYPTO_blind_sig_cmp (sig1->blinded_sig, + sig1->blinded_sig); } @@ -657,31 +342,31 @@ void TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp, struct GNUNET_HashContext *hash_context) { - uint32_t cipher = htonl (bp->cipher); + const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message; + uint32_t cipher = htonl (bm->cipher); GNUNET_CRYPTO_hash_context_read (hash_context, &cipher, sizeof (cipher)); - switch (bp->cipher) + switch (bm->cipher) { - case TALER_DENOMINATION_INVALID: - break; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + GNUNET_break (0); + return; + case GNUNET_CRYPTO_BSA_RSA: GNUNET_CRYPTO_hash_context_read ( hash_context, - bp->details.rsa_blinded_planchet.blinded_msg, - bp->details.rsa_blinded_planchet.blinded_msg_size); - break; - case TALER_DENOMINATION_CS: + bm->details.rsa_blinded_message.blinded_msg, + bm->details.rsa_blinded_message.blinded_msg_size); + return; + case GNUNET_CRYPTO_BSA_CS: GNUNET_CRYPTO_hash_context_read ( hash_context, - &bp->details.cs_blinded_planchet, - sizeof (bp->details.cs_blinded_planchet)); - break; - default: - GNUNET_assert (0); - break; + &bm->details.cs_blinded_message, + sizeof (bm->details.cs_blinded_message)); + return; } + GNUNET_assert (0); } @@ -689,14 +374,17 @@ void TALER_planchet_blinding_secret_create ( const struct TALER_PlanchetMasterSecretP *ps, const struct TALER_ExchangeWithdrawValues *alg_values, - union TALER_DenominationBlindingKeyP *bks) + union GNUNET_CRYPTO_BlindingSecretP *bks) { - switch (alg_values->cipher) + const struct GNUNET_CRYPTO_BlindingInputValues *bi = + alg_values->blinding_inputs; + + switch (bi->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_break (0); return; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&bks->rsa_bks, sizeof (bks->rsa_bks), @@ -707,7 +395,7 @@ TALER_planchet_blinding_secret_create ( NULL, 0)); return; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&bks->nonce, sizeof (bks->nonce), @@ -715,14 +403,13 @@ TALER_planchet_blinding_secret_create ( strlen ("bseed"), ps, sizeof(*ps), - &alg_values->details.cs_values, - sizeof(alg_values->details.cs_values), + &bi->details.cs_values, + sizeof(bi->details.cs_values), NULL, 0)); return; - default: - GNUNET_break (0); } + GNUNET_assert (0); } @@ -732,9 +419,18 @@ TALER_planchet_setup_coin_priv ( const struct TALER_ExchangeWithdrawValues *alg_values, struct TALER_CoinSpendPrivateKeyP *coin_priv) { - switch (alg_values->cipher) + const struct GNUNET_CRYPTO_BlindingInputValues *bi + = alg_values->blinding_inputs; + + switch (bi->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + GNUNET_break (0); + memset (coin_priv, + 0, + sizeof (*coin_priv)); + return; + case GNUNET_CRYPTO_BSA_RSA: GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (coin_priv, sizeof (*coin_priv), @@ -744,8 +440,8 @@ TALER_planchet_setup_coin_priv ( sizeof(*ps), NULL, 0)); - break; - case TALER_DENOMINATION_CS: + return; + case GNUNET_CRYPTO_BSA_CS: GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (coin_priv, sizeof (*coin_priv), @@ -753,37 +449,24 @@ TALER_planchet_setup_coin_priv ( strlen ("coin"), ps, sizeof(*ps), - &alg_values->details.cs_values, - sizeof(alg_values->details.cs_values), + &bi->details.cs_values, + sizeof(bi->details.cs_values), NULL, 0)); - break; - default: - GNUNET_break (0); return; } + GNUNET_assert (0); } void TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet) { - switch (blinded_planchet->cipher) + if (NULL != blinded_planchet->blinded_message) { - case TALER_DENOMINATION_INVALID: - GNUNET_break (0); - return; - case TALER_DENOMINATION_RSA: - GNUNET_free (blinded_planchet->details.rsa_blinded_planchet.blinded_msg); - return; - case TALER_DENOMINATION_CS: - memset (blinded_planchet, - 0, - sizeof (*blinded_planchet)); - /* nothing to do for CS */ - return; + GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message); + blinded_planchet->blinded_message = NULL; } - GNUNET_assert (0); } diff --git a/src/util/payto.c b/src/util/payto.c index 9b0e83e85..6b22a0092 100644 --- a/src/util/payto.c +++ b/src/util/payto.c @@ -205,7 +205,7 @@ TALER_payto_validate (const char *payto_uri) /* This is more strict than RFC 8905, alas we do not need to support messages/instructions/etc., and it is generally better to start with a narrow whitelist; we can be more permissive later ...*/ #define ALLOWED_CHARACTERS \ - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/:&?-.,=+" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/:&?-.,=+%" if (NULL == strchr (ALLOWED_CHARACTERS, (int) payto_uri[i])) { diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c index ed0eba15d..a9696ee84 100644 --- a/src/util/taler-exchange-secmod-cs.c +++ b/src/util/taler-exchange-secmod-cs.c @@ -269,7 +269,7 @@ struct BatchJob /** * Result with the signature. */ - struct TALER_BlindedDenominationCsSignAnswer cs_answer; + struct GNUNET_CRYPTO_CsBlindSignature cs_answer; } sign; /** @@ -285,7 +285,7 @@ struct BatchJob /** * Pair of points to return. */ - struct TALER_DenominationCSPublicRPairP rpairp; + struct GNUNET_CRYPTO_CSPublicRPairP rpairp; } rderive; @@ -433,7 +433,7 @@ generate_response (struct DenominationKey *dk) /** * Do the actual signing work. * - * @param h_cs key to sign with + * @param h_cs hash of key to sign with * @param planchet message to sign * @param for_melt true if for melting * @param[out] cs_sigp set to the CS signature @@ -441,9 +441,9 @@ generate_response (struct DenominationKey *dk) */ static enum TALER_ErrorCode do_sign (const struct TALER_CsPubHashP *h_cs, - const struct TALER_BlindedCsPlanchet *planchet, + const struct GNUNET_CRYPTO_CsBlindedMessage *planchet, bool for_melt, - struct TALER_BlindedDenominationCsSignAnswer *cs_sigp) + struct GNUNET_CRYPTO_CsBlindSignature *cs_sigp) { struct GNUNET_CRYPTO_CsRSecret r[2]; struct DenominationKey *dk; @@ -473,15 +473,14 @@ do_sign (const struct TALER_CsPubHashP *h_cs, GNUNET_assert (dk->rc < UINT_MAX); dk->rc++; GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); - GNUNET_CRYPTO_cs_r_derive (&planchet->nonce.nonce, + GNUNET_CRYPTO_cs_r_derive (&planchet->nonce, for_melt ? "rm" : "rw", &dk->denom_priv, r); - cs_sigp->b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv, - r, - planchet->c, - &planchet->nonce.nonce, - &cs_sigp->s_scalar); + GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv, + r, + planchet, + cs_sigp); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (dk->rc > 0); dk->rc--; @@ -543,14 +542,14 @@ fail_derive (struct TES_Client *client, */ static enum GNUNET_GenericReturnValue send_signature (struct TES_Client *client, - const struct TALER_BlindedDenominationCsSignAnswer *cs_answer) + const struct GNUNET_CRYPTO_CsBlindSignature *cs_answer) { struct TALER_CRYPTO_SignResponse sres; sres.header.size = htons (sizeof (sres)); sres.header.type = htons (TALER_HELPER_CS_MT_RES_SIGNATURE); - sres.reserved = htonl (0); - sres.cs_answer = *cs_answer; + sres.b = htonl (cs_answer->b); + sres.cs_answer = cs_answer->s_scalar; return TES_transmit (client->csock, &sres.header); } @@ -569,13 +568,13 @@ static enum GNUNET_GenericReturnValue handle_sign_request (struct TES_Client *client, const struct TALER_CRYPTO_CsSignRequestMessage *sr) { - struct TALER_BlindedDenominationCsSignAnswer cs_answer; + struct GNUNET_CRYPTO_CsBlindSignature cs_answer; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); enum TALER_ErrorCode ec; enum GNUNET_GenericReturnValue ret; ec = do_sign (&sr->h_cs, - &sr->planchet, + &sr->message, (0 != ntohl (sr->for_melt)), &cs_answer); if (TALER_EC_NONE != ec) @@ -605,12 +604,12 @@ handle_sign_request (struct TES_Client *client, */ static enum TALER_ErrorCode do_derive (const struct TALER_CsPubHashP *h_cs, - const struct TALER_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, bool for_melt, - struct TALER_DenominationCSPublicRPairP *rpairp) + struct GNUNET_CRYPTO_CSPublicRPairP *rpairp) { struct DenominationKey *dk; - struct TALER_DenominationCSPrivateRPairP r_priv; + struct GNUNET_CRYPTO_CSPrivateRPairP r_priv; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); dk = GNUNET_CONTAINER_multihashmap_get (keys, @@ -637,7 +636,7 @@ do_derive (const struct TALER_CsPubHashP *h_cs, GNUNET_assert (dk->rc < UINT_MAX); dk->rc++; GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); - GNUNET_CRYPTO_cs_r_derive (&nonce->nonce, + GNUNET_CRYPTO_cs_r_derive (nonce, for_melt ? "rm" : "rw", &dk->denom_priv, r_priv.r); @@ -662,10 +661,10 @@ do_derive (const struct TALER_CsPubHashP *h_cs, */ static enum GNUNET_GenericReturnValue send_derivation (struct TES_Client *client, - const struct TALER_DenominationCSPublicRPairP *r_pub) + const struct GNUNET_CRYPTO_CSPublicRPairP *r_pub) { struct TALER_CRYPTO_RDeriveResponse rdr = { - .header.size = htons (sizeof (struct TALER_CRYPTO_RDeriveResponse)), + .header.size = htons (sizeof (rdr)), .header.type = htons (TALER_HELPER_CS_MT_RES_RDERIVE), .r_pub = *r_pub }; @@ -776,7 +775,7 @@ worker (void *cls) = bj->details.sign.sr; bj->ec = do_sign (&sr->h_cs, - &sr->planchet, + &sr->message, (0 != ntohl (sr->for_melt)), &bj->details.sign.cs_answer); break; @@ -1093,8 +1092,9 @@ setup_key (struct DenominationKey *dk, GNUNET_CRYPTO_cs_private_key_generate (&priv); GNUNET_CRYPTO_cs_private_key_get_public (&priv, &pub); - TALER_cs_pub_hash (&pub, - &dk->h_cs); + GNUNET_CRYPTO_hash (&pub, + sizeof (pub), + &dk->h_cs.hash); GNUNET_asprintf (&dk->filename, "%s/%s/%llu", keydir, @@ -1242,7 +1242,7 @@ static enum GNUNET_GenericReturnValue handle_r_derive_request (struct TES_Client *client, const struct TALER_CRYPTO_CsRDeriveRequest *rdr) { - struct TALER_DenominationCSPublicRPairP r_pub; + struct GNUNET_CRYPTO_CSPublicRPairP r_pub; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); enum TALER_ErrorCode ec; enum GNUNET_GenericReturnValue ret; @@ -1773,20 +1773,19 @@ parse_key (struct Denomination *denom, return; } { - struct GNUNET_CRYPTO_CsPublicKey pub; struct DenominationKey *dk; struct DenominationKey *before; - GNUNET_CRYPTO_cs_private_key_get_public (priv, - &pub); dk = GNUNET_new (struct DenominationKey); dk->denom_priv = *priv; dk->denom = denom; dk->anchor = anchor; dk->filename = GNUNET_strdup (filename); - TALER_cs_pub_hash (&pub, - &dk->h_cs); - dk->denom_pub = pub; + GNUNET_CRYPTO_cs_private_key_get_public (priv, + &dk->denom_pub); + GNUNET_CRYPTO_hash (&dk->denom_pub, + sizeof (dk->denom_pub), + &dk->h_cs.hash); generate_response (dk); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( @@ -1808,7 +1807,9 @@ parse_key (struct Denomination *denom, NULL != pos; pos = pos->next) { - if (GNUNET_TIME_timestamp_cmp (pos->anchor, >, anchor)) + if (GNUNET_TIME_timestamp_cmp (pos->anchor, + >, + anchor)) break; before = pos; } diff --git a/src/util/taler-exchange-secmod-cs.h b/src/util/taler-exchange-secmod-cs.h index fd550efbc..0321335da 100644 --- a/src/util/taler-exchange-secmod-cs.h +++ b/src/util/taler-exchange-secmod-cs.h @@ -136,9 +136,9 @@ struct TALER_CRYPTO_CsSignRequestMessage struct TALER_CsPubHashP h_cs; /** - * Planchet containing message to sign and nonce to derive R from + * Message to sign. */ - struct TALER_BlindedCsPlanchet planchet; + struct GNUNET_CRYPTO_CsBlindedMessage message; }; @@ -188,7 +188,7 @@ struct TALER_CRYPTO_CsRDeriveRequest /** * Withdraw nonce to derive R from */ - struct TALER_CsNonce nonce; + struct GNUNET_CRYPTO_CsSessionNonce nonce; }; @@ -248,14 +248,14 @@ struct TALER_CRYPTO_SignResponse struct GNUNET_MessageHeader header; /** - * For now, always zero. + * The chosen 'b' (0 or 1). */ - uint32_t reserved; + uint32_t b; /** - * Contains the blindided s and the chosen b + * Contains the blindided s. */ - struct TALER_BlindedDenominationCsSignAnswer cs_answer; + struct GNUNET_CRYPTO_CsBlindS cs_answer; }; /** @@ -274,9 +274,9 @@ struct TALER_CRYPTO_RDeriveResponse uint32_t reserved; /** - * derived R + * Pair of derived R values */ - struct TALER_DenominationCSPublicRPairP r_pub; + struct GNUNET_CRYPTO_CSPublicRPairP r_pub; }; diff --git a/src/util/taler-exchange-secmod-rsa.c b/src/util/taler-exchange-secmod-rsa.c index 414cb4acc..b10e7c637 100644 --- a/src/util/taler-exchange-secmod-rsa.c +++ b/src/util/taler-exchange-secmod-rsa.c @@ -409,15 +409,13 @@ generate_response (struct DenominationKey *dk) * Do the actual signing work. * * @param h_rsa key to sign with - * @param blinded_msg message to sign - * @param blinded_msg_size number of bytes in @a blinded_msg + * @param bm blinded message to sign * @param[out] rsa_signaturep set to the RSA signature * @return #TALER_EC_NONE on success */ static enum TALER_ErrorCode do_sign (const struct TALER_RsaPubHashP *h_rsa, - const void *blinded_msg, - size_t blinded_msg_size, + const struct GNUNET_CRYPTO_RsaBlindedMessage *bm, struct GNUNET_CRYPTO_RsaSignature **rsa_signaturep) { struct DenominationKey *dk; @@ -447,15 +445,14 @@ do_sign (const struct TALER_RsaPubHashP *h_rsa, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received request to sign over %u bytes with key %s\n", - (unsigned int) blinded_msg_size, + (unsigned int) bm->blinded_msg_size, GNUNET_h2s (&h_rsa->hash)); GNUNET_assert (dk->rc < UINT_MAX); dk->rc++; GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); rsa_signature = GNUNET_CRYPTO_rsa_sign_blinded (dk->denom_priv, - blinded_msg, - blinded_msg_size); + bm); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (dk->rc > 0); dk->rc--; @@ -548,14 +545,15 @@ static enum GNUNET_GenericReturnValue handle_sign_request (struct TES_Client *client, const struct TALER_CRYPTO_SignRequest *sr) { - const void *blinded_msg = &sr[1]; - size_t blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr); + struct GNUNET_CRYPTO_RsaBlindedMessage bm = { + .blinded_msg = (void *) &sr[1], + .blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr) + }; struct GNUNET_CRYPTO_RsaSignature *rsa_signature; enum TALER_ErrorCode ec; ec = do_sign (&sr->h_rsa, - blinded_msg, - blinded_msg_size, + &bm, &rsa_signature); if (TALER_EC_NONE != ec) { @@ -660,12 +658,13 @@ worker (void *cls) { struct BatchJob *bj = w->job; const struct TALER_CRYPTO_SignRequest *sr = bj->sr; - const void *blinded_msg = &sr[1]; - size_t blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr); + struct GNUNET_CRYPTO_RsaBlindedMessage bm = { + .blinded_msg = (void *) &sr[1], + .blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr) + }; bj->ec = do_sign (&sr->h_rsa, - blinded_msg, - blinded_msg_size, + &bm, &bj->rsa_signature); sem_up (&bj->sem); w->job = NULL; @@ -880,8 +879,8 @@ setup_key (struct DenominationKey *dk, } buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv, &buf); - TALER_rsa_pub_hash (pub, - &dk->h_rsa); + GNUNET_CRYPTO_rsa_public_key_hash (pub, + &dk->h_rsa.hash); GNUNET_asprintf (&dk->filename, "%s/%s/%llu", keydir, @@ -1545,8 +1544,8 @@ parse_key (struct Denomination *denom, dk->denom = denom; dk->anchor = anchor; dk->filename = GNUNET_strdup (filename); - TALER_rsa_pub_hash (pub, - &dk->h_rsa); + GNUNET_CRYPTO_rsa_public_key_hash (pub, + &dk->h_rsa.hash); dk->denom_pub = pub; generate_response (dk); if (GNUNET_OK != diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c index 54f7e794d..2a2090952 100644 --- a/src/util/test_crypto.c +++ b/src/util/test_crypto.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015, 2020-2022 Taler Systems SA + (C) 2015, 2020-2023 Taler Systems SA TALER 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 @@ -37,14 +37,21 @@ test_high_level (void) struct TALER_TransferPublicKeyP trans_pub; struct TALER_TransferSecretP secret; struct TALER_TransferSecretP secret2; - union TALER_DenominationBlindingKeyP bks1; - union TALER_DenominationBlindingKeyP bks2; + union GNUNET_CRYPTO_BlindingSecretP bks1; + union GNUNET_CRYPTO_BlindingSecretP bks2; struct TALER_CoinSpendPrivateKeyP coin_priv1; struct TALER_CoinSpendPrivateKeyP coin_priv2; struct TALER_PlanchetMasterSecretP ps1; struct TALER_PlanchetMasterSecretP ps2; - struct TALER_ExchangeWithdrawValues alg1; - struct TALER_ExchangeWithdrawValues alg2; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_RSA + }; + struct TALER_ExchangeWithdrawValues alg1 = { + .blinding_inputs = &bi + }; + struct TALER_ExchangeWithdrawValues alg2 = { + .blinding_inputs = &bi + }; GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv, @@ -70,14 +77,12 @@ test_high_level (void) TALER_transfer_secret_to_planchet_secret (&secret, 0, &ps1); - alg1.cipher = TALER_DENOMINATION_RSA; TALER_planchet_setup_coin_priv (&ps1, &alg1, &coin_priv1); TALER_planchet_blinding_secret_create (&ps1, &alg1, &bks1); - alg2.cipher = TALER_DENOMINATION_RSA; TALER_transfer_secret_to_planchet_secret (&secret, 1, &ps2); @@ -116,10 +121,10 @@ test_planchets_rsa (uint8_t age) { struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_DenominationPrivateKey dk_priv; struct TALER_DenominationPublicKey dk_pub; - struct TALER_ExchangeWithdrawValues alg_values; + const struct TALER_ExchangeWithdrawValues *alg_values; struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature blind_sig; struct TALER_FreshCoin coin; @@ -127,6 +132,7 @@ test_planchets_rsa (uint8_t age) struct TALER_AgeCommitmentHash *ach = NULL; struct TALER_AgeCommitmentHash ah = {0}; + alg_values = TALER_denom_ewv_rsa_singleton (); if (0 < age) { struct TALER_AgeCommitmentProof acp; @@ -152,7 +158,7 @@ test_planchets_rsa (uint8_t age) GNUNET_assert (GNUNET_SYSERR == TALER_denom_priv_create (&dk_priv, &dk_pub, - TALER_DENOMINATION_INVALID)); + GNUNET_CRYPTO_BSA_INVALID)); GNUNET_log_skip (1, GNUNET_YES); GNUNET_assert (GNUNET_SYSERR == TALER_denom_priv_create (&dk_priv, @@ -162,19 +168,19 @@ test_planchets_rsa (uint8_t age) GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dk_priv, &dk_pub, - TALER_DENOMINATION_RSA, + GNUNET_CRYPTO_BSA_RSA, 1024)); - alg_values.cipher = TALER_DENOMINATION_RSA; TALER_planchet_setup_coin_priv (&ps, - &alg_values, + alg_values, &coin_priv); TALER_planchet_blinding_secret_create (&ps, - &alg_values, + alg_values, &bks); GNUNET_assert (GNUNET_OK == TALER_planchet_prepare (&dk_pub, - &alg_values, + alg_values, &bks, + NULL, &coin_priv, ach, &c_hash, @@ -192,7 +198,7 @@ test_planchets_rsa (uint8_t age) &coin_priv, ach, &c_hash, - &alg_values, + alg_values, &coin)); TALER_blinded_denom_sig_free (&blind_sig); TALER_denom_sig_free (&coin.sig); @@ -203,39 +209,6 @@ test_planchets_rsa (uint8_t age) /** - * @brief Function for CS signatures to derive public R_0 and R_1 - * - * @param nonce withdraw nonce from a client - * @param denom_priv denomination privkey as long-term secret - * @param r_pub the resulting R_0 and R_1 - * @return enum GNUNET_GenericReturnValue - */ -static enum GNUNET_GenericReturnValue -derive_r_public ( - const struct TALER_CsNonce *nonce, - const struct TALER_DenominationPrivateKey *denom_priv, - struct TALER_DenominationCSPublicRPairP *r_pub) -{ - struct GNUNET_CRYPTO_CsRSecret r[2]; - - if (denom_priv->cipher != TALER_DENOMINATION_CS) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_CRYPTO_cs_r_derive (&nonce->nonce, - "rw", - &denom_priv->details.cs_private_key, - r); - GNUNET_CRYPTO_cs_r_get_public (&r[0], - &r_pub->r_pub[0]); - GNUNET_CRYPTO_cs_r_get_public (&r[1], - &r_pub->r_pub[1]); - return GNUNET_OK; -} - - -/** * Test the basic planchet functionality of creating a fresh planchet with CS denomination * and extracting the respective signature. * @@ -246,11 +219,12 @@ test_planchets_cs (uint8_t age) { struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_DenominationPrivateKey dk_priv; struct TALER_DenominationPublicKey dk_pub; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHashP c_hash; + union GNUNET_CRYPTO_BlindSessionNonce nonce; struct TALER_BlindedDenominationSignature blind_sig; struct TALER_FreshCoin coin; struct TALER_ExchangeWithdrawValues alg_values; @@ -281,16 +255,17 @@ test_planchets_cs (uint8_t age) GNUNET_assert (GNUNET_OK == TALER_denom_priv_create (&dk_priv, &dk_pub, - TALER_DENOMINATION_CS)); - alg_values.cipher = TALER_DENOMINATION_CS; + GNUNET_CRYPTO_BSA_CS)); TALER_cs_withdraw_nonce_derive ( &ps, - &pd.blinded_planchet.details.cs_blinded_planchet.nonce); - GNUNET_assert (GNUNET_OK == - derive_r_public ( - &pd.blinded_planchet.details.cs_blinded_planchet.nonce, - &dk_priv, - &alg_values.details.cs_values)); + &nonce.cs_nonce); + // FIXME: define Taler abstraction for this: + alg_values.blinding_inputs + = GNUNET_CRYPTO_get_blinding_input_values (dk_priv.bsign_priv_key, + &nonce, + "rw"); + TALER_denom_pub_hash (&dk_pub, + &pd.denom_pub_hash); TALER_planchet_setup_coin_priv (&ps, &alg_values, &coin_priv); @@ -301,6 +276,7 @@ test_planchets_cs (uint8_t age) TALER_planchet_prepare (&dk_pub, &alg_values, &bks, + &nonce, &coin_priv, ach, &c_hash, @@ -310,7 +286,6 @@ test_planchets_cs (uint8_t age) &dk_priv, false, &pd.blinded_planchet)); - TALER_planchet_detail_free (&pd); GNUNET_assert (GNUNET_OK == TALER_planchet_to_coin (&dk_pub, &blind_sig, diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c index 2dada0e19..2292cbfd1 100644 --- a/src/util/test_helper_cs.c +++ b/src/util/test_helper_cs.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2020, 2021 Taler Systems SA + (C) 2020, 2021, 2023 Taler Systems SA TALER 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 @@ -129,7 +129,7 @@ free_keys (void) * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_cs hash of the @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bs_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -140,7 +140,7 @@ key_cb (void *cls, struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_CsPubHashP *h_cs, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { @@ -155,7 +155,7 @@ key_cb (void *cls, { bool found = false; - GNUNET_break (NULL == denom_pub); + GNUNET_break (NULL == bs_pub); GNUNET_break (NULL == section_name); for (unsigned int i = 0; i<MAX_KEYS; i++) if (0 == GNUNET_memcmp (h_cs, @@ -176,7 +176,7 @@ key_cb (void *cls, return; } - GNUNET_break (NULL != denom_pub); + GNUNET_break (NULL != bs_pub); for (unsigned int i = 0; i<MAX_KEYS; i++) if (! keys[i].valid) { @@ -184,8 +184,8 @@ key_cb (void *cls, keys[i].h_cs = *h_cs; keys[i].start_time = start_time; keys[i].validity_duration = validity_duration; - TALER_denom_pub_deep_copy (&keys[i].denom_pub, - denom_pub); + keys[i].denom_pub.bsign_pub_key + = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); num_keys++; return; } @@ -268,9 +268,15 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) bool success = false; struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_CoinPubHashP c_hash; - struct TALER_ExchangeWithdrawValues alg_values; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_CS + }; + struct TALER_ExchangeWithdrawValues alg_values = { + .blinding_inputs = &bi + }; + union GNUNET_CRYPTO_BlindSessionNonce nonce; TALER_planchet_master_setup_random (&ps); for (unsigned int i = 0; i<MAX_KEYS; i++) @@ -279,27 +285,25 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) if (! keys[i].valid) continue; - GNUNET_assert (TALER_DENOMINATION_CS == - keys[i].denom_pub.cipher); - pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; + GNUNET_assert (GNUNET_CRYPTO_BSA_CS == + keys[i].denom_pub.bsign_pub_key->cipher); TALER_cs_withdraw_nonce_derive ( &ps, - &pd.blinded_planchet.details.cs_blinded_planchet.nonce); + &nonce.cs_nonce); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting R derivation with key %s\n", GNUNET_h2s (&keys[i].h_cs.hash)); - alg_values.cipher = TALER_DENOMINATION_CS; { struct TALER_CRYPTO_CsDeriveRequest cdr = { .h_cs = &keys[i].h_cs, - .nonce = &pd.blinded_planchet.details.cs_blinded_planchet.nonce + .nonce = &nonce.cs_nonce }; ec = TALER_CRYPTO_helper_cs_r_derive ( dh, &cdr, false, - &alg_values.details.cs_values); + &bi.details.cs_values); } switch (ec) { @@ -336,10 +340,12 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) TALER_planchet_prepare (&keys[i].denom_pub, &alg_values, &bks, + &nonce, &coin_priv, NULL, /* no age commitment */ &c_hash, &pd)); + TALER_blinded_planchet_free (&pd.blinded_planchet); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Successfully prepared planchet"); success = true; @@ -379,11 +385,10 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) /* check R derivation does not work if the key is unknown */ { struct TALER_CsPubHashP rnd; - struct TALER_CsNonce nonce; - struct TALER_DenominationCSPublicRPairP crp; + struct GNUNET_CRYPTO_CSPublicRPairP crp; struct TALER_CRYPTO_CsDeriveRequest cdr = { .h_cs = &rnd, - .nonce = &nonce, + .nonce = &nonce.cs_nonce, }; GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, @@ -423,9 +428,15 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) bool success = false; struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; struct TALER_CoinPubHashP c_hash; - struct TALER_ExchangeWithdrawValues alg_values; + struct GNUNET_CRYPTO_BlindingInputValues bi = { + .cipher = GNUNET_CRYPTO_BSA_CS + }; + struct TALER_ExchangeWithdrawValues alg_values = { + .blinding_inputs = &bi + }; + union GNUNET_CRYPTO_BlindSessionNonce nonce; TALER_planchet_master_setup_random (&ps); for (unsigned int i = 0; i<MAX_KEYS; i++) @@ -437,19 +448,16 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) struct TALER_CRYPTO_CsSignRequest csr; struct TALER_CRYPTO_CsDeriveRequest cdr = { .h_cs = &keys[i].h_cs, - .nonce = &pd.blinded_planchet.details.cs_blinded_planchet.nonce + .nonce = &nonce.cs_nonce }; - pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; TALER_cs_withdraw_nonce_derive (&ps, - &pd.blinded_planchet.details. - cs_blinded_planchet.nonce); - alg_values.cipher = TALER_DENOMINATION_CS; + &nonce.cs_nonce); ec = TALER_CRYPTO_helper_cs_r_derive ( dh, &cdr, false, - &alg_values.details.cs_values); + &bi.details.cs_values); if (TALER_EC_NONE != ec) continue; TALER_planchet_setup_coin_priv (&ps, @@ -458,11 +466,11 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) TALER_planchet_blinding_secret_create (&ps, &alg_values, &bks); - GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[i].denom_pub, &alg_values, &bks, + &nonce, &coin_priv, NULL, /* no age commitment */ &c_hash, @@ -472,12 +480,13 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) GNUNET_h2s (&keys[i].h_cs.hash)); csr.h_cs = &keys[i].h_cs; csr.blinded_planchet - = &pd.blinded_planchet.details.cs_blinded_planchet; + = &pd.blinded_planchet.blinded_message->details.cs_blinded_message; ec = TALER_CRYPTO_helper_cs_sign ( dh, &csr, false, &ds); + TALER_blinded_planchet_free (&pd.blinded_planchet); } switch (ec) { @@ -489,6 +498,7 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) { /* key worked too early */ GNUNET_break (0); + TALER_blinded_denom_sig_free (&ds); return 4; } if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_duration ( @@ -498,6 +508,7 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) { /* key worked too later */ GNUNET_break (0); + TALER_blinded_denom_sig_free (&ds); return 5; } { @@ -514,8 +525,11 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) &coin)) { GNUNET_break (0); + TALER_blinded_denom_sig_free (&ds); return 6; } + TALER_blinded_denom_sig_free (&ds); + TALER_denom_sig_free (&coin.sig); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received valid signature for key %s\n", @@ -563,23 +577,24 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &rnd, sizeof (rnd)); - pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[0].denom_pub, &alg_values, &bks, + &nonce, &coin_priv, NULL, /* no age commitment */ &c_hash, &pd)); csr.h_cs = &rnd; csr.blinded_planchet - = &pd.blinded_planchet.details.cs_blinded_planchet; + = &pd.blinded_planchet.blinded_message->details.cs_blinded_message; ec = TALER_CRYPTO_helper_cs_sign ( dh, &csr, false, &ds); + TALER_blinded_planchet_free (&pd.blinded_planchet); if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) { if (TALER_EC_NONE == ec) @@ -613,9 +628,11 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, bool success = false; struct TALER_PlanchetMasterSecretP ps[batch_size]; struct TALER_CoinSpendPrivateKeyP coin_priv[batch_size]; - union TALER_DenominationBlindingKeyP bks[batch_size]; + union GNUNET_CRYPTO_BlindingSecretP bks[batch_size]; struct TALER_CoinPubHashP c_hash[batch_size]; + struct GNUNET_CRYPTO_BlindingInputValues bi[batch_size]; struct TALER_ExchangeWithdrawValues alg_values[batch_size]; + union GNUNET_CRYPTO_BlindSessionNonce nonces[batch_size]; for (unsigned int i = 0; i<batch_size; i++) TALER_planchet_master_setup_random (&ps[i]); @@ -627,30 +644,29 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, struct TALER_PlanchetDetail pd[batch_size]; struct TALER_CRYPTO_CsSignRequest csr[batch_size]; struct TALER_CRYPTO_CsDeriveRequest cdr[batch_size]; - struct TALER_DenominationCSPublicRPairP crps[batch_size]; + struct GNUNET_CRYPTO_CSPublicRPairP crps[batch_size]; for (unsigned int i = 0; i<batch_size; i++) { cdr[i].h_cs = &keys[k].h_cs; - cdr[i].nonce = - &pd[i].blinded_planchet.details.cs_blinded_planchet.nonce; - pd[i].blinded_planchet.cipher = TALER_DENOMINATION_CS; + cdr[i].nonce = &nonces[i].cs_nonce; TALER_cs_withdraw_nonce_derive ( &ps[i], - &pd[i].blinded_planchet.details.cs_blinded_planchet.nonce); - alg_values[i].cipher = TALER_DENOMINATION_CS; + &nonces[i].cs_nonce); + bi[i].cipher = GNUNET_CRYPTO_BSA_CS; + alg_values[i].blinding_inputs = &bi[i]; } ec = TALER_CRYPTO_helper_cs_r_batch_derive ( dh, - cdr, batch_size, + cdr, false, crps); if (TALER_EC_NONE != ec) continue; for (unsigned int i = 0; i<batch_size; i++) { - alg_values[i].details.cs_values = crps[i]; + bi[i].details.cs_values = crps[i]; TALER_planchet_setup_coin_priv (&ps[i], &alg_values[i], &coin_priv[i]); @@ -661,6 +677,7 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, TALER_planchet_prepare (&keys[k].denom_pub, &alg_values[i], &bks[i], + &nonces[i], &coin_priv[i], NULL, /* no age commitment */ &c_hash[i], @@ -670,14 +687,18 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, GNUNET_h2s (&keys[k].h_cs.hash)); csr[i].h_cs = &keys[k].h_cs; csr[i].blinded_planchet - = &pd[i].blinded_planchet.details.cs_blinded_planchet; + = &pd[i].blinded_planchet.blinded_message->details.cs_blinded_message; } ec = TALER_CRYPTO_helper_cs_batch_sign ( dh, - csr, batch_size, + csr, false, ds); + for (unsigned int i = 0; i<batch_size; i++) + { + TALER_blinded_planchet_free (&pd[i].blinded_planchet); + } } switch (ec) { @@ -719,11 +740,18 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, GNUNET_break (0); return 6; } + TALER_blinded_denom_sig_free (&ds[i]); + TALER_denom_sig_free (&coin.sig); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received valid signature for key %s\n", GNUNET_h2s (&keys[k].h_cs.hash)); } + else + { + for (unsigned int i = 0; i<batch_size; i++) + TALER_blinded_denom_sig_free (&ds[i]); + } success = true; break; case TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY: @@ -768,28 +796,29 @@ test_batch_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &rnd, sizeof (rnd)); - pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[0].denom_pub, &alg_values[0], &bks[0], + &nonces[0], &coin_priv[0], NULL, /* no age commitment */ &c_hash[0], &pd)); csr.h_cs = &rnd; csr.blinded_planchet - = &pd.blinded_planchet.details.cs_blinded_planchet; + = &pd.blinded_planchet.blinded_message->details.cs_blinded_message; ec = TALER_CRYPTO_helper_cs_batch_sign ( dh, - &csr, 1, + &csr, false, &ds[0]); + TALER_blinded_planchet_free (&pd.blinded_planchet); if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) { if (TALER_EC_NONE == ec) - TALER_blinded_denom_sig_free (ds); + TALER_blinded_denom_sig_free (&ds[0]); GNUNET_break (0); return 17; } @@ -816,8 +845,13 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, struct GNUNET_TIME_Relative duration; struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; - struct TALER_ExchangeWithdrawValues alg_values; + union GNUNET_CRYPTO_BlindingSecretP bks; + struct GNUNET_CRYPTO_BlindingInputValues bv = { + .cipher = GNUNET_CRYPTO_BSA_CS + }; + struct TALER_ExchangeWithdrawValues alg_values = { + .blinding_inputs = &bv + }; TALER_planchet_master_setup_random (&ps); duration = GNUNET_TIME_UNIT_ZERO; @@ -841,21 +875,20 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, { struct TALER_CoinPubHashP c_hash; struct TALER_PlanchetDetail pd; + union GNUNET_CRYPTO_BlindSessionNonce nonce; struct TALER_CRYPTO_CsDeriveRequest cdr = { .h_cs = &keys[i].h_cs, - .nonce = &pd.blinded_planchet.details.cs_blinded_planchet.nonce + .nonce = &nonce.cs_nonce }; - pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; - TALER_cs_withdraw_nonce_derive (&ps, - &pd.blinded_planchet.details. - cs_blinded_planchet.nonce); - alg_values.cipher = TALER_DENOMINATION_CS; + TALER_cs_withdraw_nonce_derive ( + &ps, + &nonce.cs_nonce); ec = TALER_CRYPTO_helper_cs_r_derive ( dh, &cdr, true, - &alg_values.details.cs_values); + &bv.details.cs_values); if (TALER_EC_NONE != ec) continue; TALER_planchet_setup_coin_priv (&ps, @@ -868,6 +901,7 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, TALER_planchet_prepare (&keys[i].denom_pub, &alg_values, &bks, + &nonce, &coin_priv, NULL, /* no age commitment */ &c_hash, @@ -881,7 +915,7 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, csr.h_cs = &keys[i].h_cs; csr.blinded_planchet - = &pd.blinded_planchet.details.cs_blinded_planchet; + = &pd.blinded_planchet.blinded_message->details.cs_blinded_message; ec = TALER_CRYPTO_helper_cs_sign ( dh, &csr, @@ -897,9 +931,10 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, if (NUM_SIGN_PERFS <= j) break; } + TALER_blinded_planchet_free (&pd.blinded_planchet); } - } /* for i */ - } /* for j */ + } /* for i */ + } /* for j */ fprintf (stderr, "%u (%s) signature operations took %s\n", (unsigned int) NUM_SIGN_PERFS, diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c index 1c7cc5bfe..028e23c74 100644 --- a/src/util/test_helper_rsa.c +++ b/src/util/test_helper_rsa.c @@ -129,7 +129,7 @@ free_keys (void) * @param validity_duration how long does the key remain available for signing; * zero if the key has been revoked or purged * @param h_rsa hash of the @a denom_pub that is available (or was purged) - * @param denom_pub the public key itself, NULL if the key was revoked or purged + * @param bs_pub the public key itself, NULL if the key was revoked or purged * @param sm_pub public key of the security module, NULL if the key was revoked or purged * @param sm_sig signature from the security module, NULL if the key was revoked or purged * The signature was already verified against @a sm_pub. @@ -140,7 +140,7 @@ key_cb (void *cls, struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Relative validity_duration, const struct TALER_RsaPubHashP *h_rsa, - const struct TALER_DenominationPublicKey *denom_pub, + struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { @@ -155,7 +155,7 @@ key_cb (void *cls, { bool found = false; - GNUNET_break (NULL == denom_pub); + GNUNET_break (NULL == bs_pub); GNUNET_break (NULL == section_name); for (unsigned int i = 0; i<MAX_KEYS; i++) if (0 == GNUNET_memcmp (h_rsa, @@ -176,7 +176,7 @@ key_cb (void *cls, return; } - GNUNET_break (NULL != denom_pub); + GNUNET_break (NULL != bs_pub); for (unsigned int i = 0; i<MAX_KEYS; i++) if (! keys[i].valid) { @@ -184,8 +184,8 @@ key_cb (void *cls, keys[i].h_rsa = *h_rsa; keys[i].start_time = start_time; keys[i].validity_duration = validity_duration; - TALER_denom_pub_deep_copy (&keys[i].denom_pub, - denom_pub); + keys[i].denom_pub.bsign_pub_key + = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); num_keys++; return; } @@ -268,19 +268,22 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh) enum TALER_ErrorCode ec; bool success = false; struct TALER_PlanchetMasterSecretP ps; - struct TALER_ExchangeWithdrawValues alg_values; + const struct TALER_ExchangeWithdrawValues *alg_values + = TALER_denom_ewv_rsa_singleton (); struct TALER_AgeCommitmentHash ach; struct TALER_CoinPubHashP c_hash; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, &ps, sizeof (ps)); - - alg_values.cipher = TALER_DENOMINATION_RSA; - TALER_planchet_setup_coin_priv (&ps, &alg_values, &coin_priv); - TALER_planchet_blinding_secret_create (&ps, &alg_values, &bks); + TALER_planchet_setup_coin_priv (&ps, + alg_values, + &coin_priv); + TALER_planchet_blinding_secret_create (&ps, + alg_values, + &bks); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &ach, sizeof(ach)); @@ -289,17 +292,17 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh) { if (! keys[i].valid) continue; - if (TALER_DENOMINATION_RSA != keys[i].denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_RSA != + keys[i].denom_pub.bsign_pub_key->cipher) continue; { - struct TALER_PlanchetDetail pd = { - .blinded_planchet.cipher = TALER_DENOMINATION_RSA - }; + struct TALER_PlanchetDetail pd; GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[i].denom_pub, - &alg_values, + alg_values, &bks, + NULL, &coin_priv, &ach, &c_hash, @@ -308,9 +311,11 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh) struct TALER_CRYPTO_RsaSignRequest rsr = { .h_rsa = &keys[i].h_rsa, .msg = - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg, + pd.blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg, .msg_size = - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size + pd.blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg_size }; GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -352,7 +357,7 @@ test_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh) &ds, &bks, &c_hash, - &alg_values, + alg_values, &keys[i].denom_pub)) { GNUNET_break (0); @@ -457,11 +462,11 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, enum TALER_ErrorCode ec; bool success = false; struct TALER_PlanchetMasterSecretP ps[batch_size]; - struct TALER_ExchangeWithdrawValues alg_values[batch_size]; + const struct TALER_ExchangeWithdrawValues *alg_values; struct TALER_AgeCommitmentHash ach[batch_size]; struct TALER_CoinPubHashP c_hash[batch_size]; struct TALER_CoinSpendPrivateKeyP coin_priv[batch_size]; - union TALER_DenominationBlindingKeyP bks[batch_size]; + union GNUNET_CRYPTO_BlindingSecretP bks[batch_size]; GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, &ps, @@ -469,14 +474,14 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &ach, sizeof(ach)); + alg_values = TALER_denom_ewv_rsa_singleton (); for (unsigned int i = 0; i<batch_size; i++) { - alg_values[i].cipher = TALER_DENOMINATION_RSA; TALER_planchet_setup_coin_priv (&ps[i], - &alg_values[i], + alg_values, &coin_priv[i]); TALER_planchet_blinding_secret_create (&ps[i], - &alg_values[i], + alg_values, &bks[i]); } for (unsigned int k = 0; k<MAX_KEYS; k++) @@ -485,7 +490,8 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, break; /* only do one round */ if (! keys[k].valid) continue; - if (TALER_DENOMINATION_RSA != keys[k].denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_RSA != + keys[k].denom_pub.bsign_pub_key->cipher) continue; { struct TALER_PlanchetDetail pd[batch_size]; @@ -493,11 +499,11 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, for (unsigned int i = 0; i<batch_size; i++) { - pd[i].blinded_planchet.cipher = TALER_DENOMINATION_RSA; GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[k].denom_pub, - &alg_values[i], + alg_values, &bks[i], + NULL, &coin_priv[i], &ach[i], &c_hash[i], @@ -505,19 +511,21 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, rsr[i].h_rsa = &keys[k].h_rsa; rsr[i].msg - = pd[i].blinded_planchet.details.rsa_blinded_planchet.blinded_msg; + = pd[i].blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg; rsr[i].msg_size - = pd[i].blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size; + = pd[i].blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg_size; } ec = TALER_CRYPTO_helper_rsa_batch_sign (dh, - rsr, batch_size, + rsr, ds); for (unsigned int i = 0; i<batch_size; i++) { if (TALER_EC_NONE == ec) - GNUNET_break (TALER_DENOMINATION_RSA == - ds[i].cipher); + GNUNET_break (GNUNET_CRYPTO_BSA_RSA == + ds[i].blinded_sig->cipher); TALER_blinded_planchet_free (&pd[i].blinded_planchet); } } @@ -553,7 +561,7 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, &ds[i], &bks[i], &c_hash[i], - &alg_values[i], + alg_values, &keys[k].denom_pub)) { GNUNET_break (0); @@ -637,8 +645,8 @@ test_batch_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, &rnd, sizeof (rnd)); ec = TALER_CRYPTO_helper_rsa_batch_sign (dh, - &rsr, 1, + &rsr, ds); if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) { @@ -674,13 +682,17 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, struct TALER_PlanchetMasterSecretP ps; struct TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_AgeCommitmentHash ach; - union TALER_DenominationBlindingKeyP bks; - struct TALER_ExchangeWithdrawValues alg_values; + union GNUNET_CRYPTO_BlindingSecretP bks; + const struct TALER_ExchangeWithdrawValues *alg_values + = TALER_denom_ewv_rsa_singleton (); TALER_planchet_master_setup_random (&ps); - alg_values.cipher = TALER_DENOMINATION_RSA; - TALER_planchet_setup_coin_priv (&ps, &alg_values, &coin_priv); - TALER_planchet_blinding_secret_create (&ps, &alg_values, &bks); + TALER_planchet_setup_coin_priv (&ps, + alg_values, + &coin_priv); + TALER_planchet_blinding_secret_create (&ps, + alg_values, + &bks); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &ach, sizeof(ach)); @@ -692,7 +704,8 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, { if (! keys[i].valid) continue; - if (TALER_DENOMINATION_RSA != keys[i].denom_pub.cipher) + if (GNUNET_CRYPTO_BSA_RSA != + keys[i].denom_pub.bsign_pub_key->cipher) continue; if (GNUNET_TIME_relative_cmp (GNUNET_TIME_absolute_get_remaining ( keys[i].start_time.abs_time), @@ -710,8 +723,9 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[i].denom_pub, - &alg_values, + alg_values, &bks, + NULL, &coin_priv, &ach, &c_hash, @@ -724,9 +738,11 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, struct TALER_CRYPTO_RsaSignRequest rsr = { .h_rsa = &keys[i].h_rsa, .msg = - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg, + pd.blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg, .msg_size = - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size + pd.blinded_planchet.blinded_message->details.rsa_blinded_message. + blinded_msg_size }; ec = TALER_CRYPTO_helper_rsa_sign (dh, diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 897f7f986..0b6ab5432 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -320,7 +320,7 @@ struct TALER_RecoupRequestPS /** * Blinding factor that was used to withdraw the coin. */ - union TALER_DenominationBlindingKeyP coin_blind; + union GNUNET_CRYPTO_BlindingSecretP coin_blind; }; @@ -330,7 +330,7 @@ GNUNET_NETWORK_STRUCT_END enum GNUNET_GenericReturnValue TALER_wallet_recoup_verify ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig) { @@ -351,7 +351,7 @@ TALER_wallet_recoup_verify ( void TALER_wallet_recoup_sign ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig) { @@ -371,7 +371,7 @@ TALER_wallet_recoup_sign ( enum GNUNET_GenericReturnValue TALER_wallet_recoup_refresh_verify ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig) { @@ -392,7 +392,7 @@ TALER_wallet_recoup_refresh_verify ( void TALER_wallet_recoup_refresh_sign ( const struct TALER_DenominationHashP *h_denom_pub, - const union TALER_DenominationBlindingKeyP *coin_bks, + const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig) { @@ -1543,6 +1543,7 @@ struct TALER_ReserveOpenDepositPS GNUNET_NETWORK_STRUCT_END +// FIXME-#7267: add h_age_commitment, h_denom_pub to have proof! void TALER_wallet_reserve_open_deposit_sign ( const struct TALER_Amount *coin_contribution, |