aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Blättler <blatc2@bfh.ch>2023-11-07 15:11:28 +0100
committerChristian Blättler <blatc2@bfh.ch>2023-11-07 15:11:28 +0100
commit247e96cff1204cebd87e965cbf698e3506efdc52 (patch)
treea3f5f829e1777d05072547a8b6e125e48a944a77 /src
parent92c3189b150ff79c8ce0f5a296e2cdddbe132519 (diff)
parent2992b42baedc5c2f5afeaef89c55604c45849370 (diff)
Merge branch 'master' into feature/tokens
Diffstat (limited to 'src')
-rw-r--r--src/auditor/taler-helper-auditor-coins.c6
-rw-r--r--src/auditor/taler-helper-auditor-deposits.c21
-rw-r--r--src/auditor/taler-helper-auditor-reserves.c2
-rw-r--r--src/auditordb/0002-auditor_balances.sql20
-rw-r--r--src/auditordb/0002-auditor_denomination_pending.sql1
-rw-r--r--src/auditordb/0002-auditor_deposit_confirmations.sql44
-rw-r--r--src/auditordb/0002-auditor_exchange_signkeys.sql1
-rw-r--r--src/auditordb/0002-auditor_historic_denomination_revenue.sql1
-rw-r--r--src/auditordb/0002-auditor_historic_reserve_summary.sql1
-rw-r--r--src/auditordb/0002-auditor_purses.sql5
-rw-r--r--src/auditordb/0002-auditor_reserves.sql1
-rw-r--r--src/auditordb/0002-deposit_confirmations.sql35
-rw-r--r--src/auditordb/auditor-0001.sql7
-rw-r--r--src/auditordb/auditor-0002.sql.in21
-rw-r--r--src/auditordb/test_auditordb.c2
-rw-r--r--src/benchmark/taler-aggregator-benchmark.c15
-rw-r--r--src/exchange-tools/taler-exchange-offline.c21
-rw-r--r--src/exchange/taler-exchange-httpd_age-withdraw.c22
-rw-r--r--src/exchange/taler-exchange-httpd_age-withdraw_reveal.c60
-rw-r--r--src/exchange/taler-exchange-httpd_batch-deposit.c9
-rw-r--r--src/exchange/taler-exchange-httpd_batch-withdraw.c21
-rw-r--r--src/exchange/taler-exchange-httpd_common_deposit.c9
-rw-r--r--src/exchange/taler-exchange-httpd_csr.c49
-rw-r--r--src/exchange/taler-exchange-httpd_extensions.c12
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c301
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h12
-rw-r--r--src/exchange/taler-exchange-httpd_management_post_keys.c289
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c6
-rw-r--r--src/exchange/taler-exchange-httpd_recoup-refresh.c33
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c31
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c72
-rw-r--r--src/exchangedb/perf_deposits_get_ready.c18
-rw-r--r--src/exchangedb/perf_get_link_data.c17
-rw-r--r--src/exchangedb/perf_select_refunds_by_coin.c18
-rw-r--r--src/exchangedb/pg_do_age_withdraw.c11
-rw-r--r--src/exchangedb/pg_do_batch_withdraw_insert.c2
-rw-r--r--src/exchangedb/pg_do_batch_withdraw_insert.h2
-rw-r--r--src/exchangedb/pg_do_deposit.c11
-rw-r--r--src/exchangedb/pg_do_recoup.c2
-rw-r--r--src/exchangedb/pg_do_recoup.h2
-rw-r--r--src/exchangedb/pg_do_recoup_refresh.c2
-rw-r--r--src/exchangedb/pg_do_recoup_refresh.h2
-rw-r--r--src/exchangedb/pg_get_age_withdraw.c10
-rw-r--r--src/exchangedb/pg_get_extension_manifest.c9
-rw-r--r--src/exchangedb/pg_get_known_coin.c4
-rw-r--r--src/exchangedb/pg_get_link_data.c6
-rw-r--r--src/exchangedb/pg_get_refresh_reveal.c4
-rw-r--r--src/exchangedb/pg_insert_kyc_attributes.c2
-rw-r--r--src/exchangedb/pg_lookup_denomination_key.c1
-rw-r--r--src/exchangedb/pg_reserves_in_insert.c1
-rw-r--r--src/exchangedb/pg_select_recoup_above_serial_id.c2
-rw-r--r--src/exchangedb/pg_select_recoup_refresh_above_serial_id.c2
-rw-r--r--src/exchangedb/test_exchangedb.c51
-rw-r--r--src/extensions/age_restriction/age_restriction.c11
-rw-r--r--src/include/taler_crypto_lib.h379
-rw-r--r--src/include/taler_exchange_service.h13
-rw-r--r--src/include/taler_exchangedb_plugin.h30
-rw-r--r--src/include/taler_json_lib.h3
-rw-r--r--src/include/taler_testing_lib.h2
-rw-r--r--src/include/taler_util.h6
-rw-r--r--src/json/json_helper.c235
-rw-r--r--src/json/json_pack.c124
-rw-r--r--src/kyclogic/Makefile.am5
-rw-r--r--src/kyclogic/kyclogic-oauth2.conf6
-rw-r--r--src/kyclogic/plugin_kyclogic_oauth2.c271
-rw-r--r--src/kyclogic/plugin_kyclogic_persona.c6
-rwxr-xr-xsrc/kyclogic/taler-exchange-kyc-kycaid-converter.sh1
-rwxr-xr-xsrc/kyclogic/taler-exchange-kyc-oauth2-challenger.sh27
-rwxr-xr-xsrc/kyclogic/taler-exchange-kyc-oauth2-nda.sh27
-rwxr-xr-xsrc/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh29
-rw-r--r--src/lib/exchange_api_age_withdraw.c132
-rw-r--r--src/lib/exchange_api_batch_withdraw.c108
-rw-r--r--src/lib/exchange_api_csr_melt.c5
-rw-r--r--src/lib/exchange_api_csr_withdraw.c14
-rw-r--r--src/lib/exchange_api_handle.c21
-rw-r--r--src/lib/exchange_api_link.c19
-rw-r--r--src/lib/exchange_api_management_get_keys.c18
-rw-r--r--src/lib/exchange_api_melt.c36
-rw-r--r--src/lib/exchange_api_recoup.c42
-rw-r--r--src/lib/exchange_api_recoup_refresh.c45
-rw-r--r--src/lib/exchange_api_refresh_common.c33
-rw-r--r--src/lib/exchange_api_refresh_common.h2
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c24
-rw-r--r--src/pq/pq_query_helper.c147
-rw-r--r--src/pq/pq_result_helper.c246
-rw-r--r--src/templating/Makefile.am3
-rw-r--r--src/testing/Makefile.am1
-rwxr-xr-xsrc/testing/taler-unified-setup.sh74
-rw-r--r--src/testing/test_exchange_api.c15
-rw-r--r--src/testing/test_exchange_api.conf2
-rw-r--r--src/testing/test_exchange_api_age_restriction.conf2
-rw-r--r--src/testing/test_kyc_api.conf3
-rw-r--r--src/testing/testing_api_cmd_batch_withdraw.c2
-rw-r--r--src/testing/testing_api_cmd_deposit.c77
-rw-r--r--src/testing/testing_api_cmd_insert_deposit.c15
-rw-r--r--src/testing/testing_api_cmd_oauth.c2
-rw-r--r--src/testing/testing_api_cmd_refresh.c23
-rw-r--r--src/testing/testing_api_cmd_withdraw.c6
-rw-r--r--src/testing/testing_api_loop.c9
-rw-r--r--src/testing/valgrind.h7165
-rw-r--r--src/util/age_restriction.c2
-rw-r--r--src/util/config.c17
-rw-r--r--src/util/conversion.c7
-rw-r--r--src/util/crypto.c43
-rw-r--r--src/util/crypto_helper_cs.c61
-rw-r--r--src/util/crypto_helper_rsa.c48
-rw-r--r--src/util/currencies.conf10
-rw-r--r--src/util/denom.c663
-rw-r--r--src/util/payto.c2
-rw-r--r--src/util/taler-exchange-secmod-cs.c67
-rw-r--r--src/util/taler-exchange-secmod-cs.h18
-rw-r--r--src/util/taler-exchange-secmod-rsa.c37
-rw-r--r--src/util/test_crypto.c93
-rw-r--r--src/util/test_helper_cs.c151
-rw-r--r--src/util/test_helper_rsa.c104
-rw-r--r--src/util/wallet_signatures.c11
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,
&currency),
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,