diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-02-20 21:51:41 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-02-20 21:51:46 +0100 |
commit | 19624fd776f28812354f7e2b50b26e984ff077ab (patch) | |
tree | 625d0019650cb88d42bbf7f5ac0c1ef51fabac70 /src/util | |
parent | dbc5adba7f22fb9568be29479ac9cf19463d471f (diff) | |
download | exchange-19624fd776f28812354f7e2b50b26e984ff077ab.tar.xz |
-ensure different HKDF is used in melt vs. withdraw
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/crypto_helper_cs.c | 114 | ||||
-rw-r--r-- | src/util/denom.c | 2 | ||||
-rw-r--r-- | src/util/taler-exchange-secmod-cs.c | 14 | ||||
-rw-r--r-- | src/util/taler-exchange-secmod-cs.h | 8 | ||||
-rw-r--r-- | src/util/test_crypto.c | 3 | ||||
-rw-r--r-- | src/util/test_helper_cs.c | 68 |
6 files changed, 160 insertions, 49 deletions
diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c index 874679cf0..e12d5ad61 100644 --- a/src/util/crypto_helper_cs.c +++ b/src/util/crypto_helper_cs.c @@ -378,11 +378,29 @@ more: } -enum TALER_ErrorCode -TALER_CRYPTO_helper_cs_sign ( +/** + * Request helper @a dh to sign @a msg using the public key corresponding to + * @a h_denom_pub. + * + * This operation will block until the signature has been obtained. Should + * this process receive a signal (that is not ignored) while the operation is + * pending, the operation will fail. Note that the helper may still believe + * that it created the signature. Thus, signals may result in a small + * differences in the signature counters. Retrying in this case may work. + * + * @param dh helper process connection + * @param h_cs hash of the CS public key to use to sign + * @param blinded_planchet blinded planchet containing c and nonce + * @param for_melt true if the HKDF for melt should be used + * @param[out] bs set to the blind signature + * @return #TALER_EC_NONE on success + */ +static enum TALER_ErrorCode +helper_cs_sign ( struct TALER_CRYPTO_CsDenominationHelper *dh, const struct TALER_CsPubHashP *h_cs, const struct TALER_BlindedCsPlanchet *blinded_planchet, + bool for_melt, struct TALER_BlindedDenominationSignature *bs) { enum TALER_ErrorCode ec = TALER_EC_INVALID; @@ -407,7 +425,7 @@ TALER_CRYPTO_helper_cs_sign ( sr->header.size = htons (sizeof (buf)); sr->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN); - sr->reserved = htonl (0); + sr->for_melt = htonl (for_melt ? 1 : 0); sr->h_cs = *h_cs; sr->planchet = *blinded_planchet; if (GNUNET_OK != @@ -573,6 +591,36 @@ end: } +enum TALER_ErrorCode +TALER_CRYPTO_helper_cs_sign_melt ( + struct TALER_CRYPTO_CsDenominationHelper *dh, + const struct TALER_CsPubHashP *h_cs, + const struct TALER_BlindedCsPlanchet *blinded_planchet, + struct TALER_BlindedDenominationSignature *bs) +{ + return helper_cs_sign (dh, + h_cs, + blinded_planchet, + true, + bs); +} + + +enum TALER_ErrorCode +TALER_CRYPTO_helper_cs_sign_withdraw ( + struct TALER_CRYPTO_CsDenominationHelper *dh, + const struct TALER_CsPubHashP *h_cs, + const struct TALER_BlindedCsPlanchet *blinded_planchet, + struct TALER_BlindedDenominationSignature *bs) +{ + return helper_cs_sign (dh, + h_cs, + blinded_planchet, + false, + bs); +} + + void TALER_CRYPTO_helper_cs_revoke ( struct TALER_CRYPTO_CsDenominationHelper *dh, @@ -603,11 +651,29 @@ TALER_CRYPTO_helper_cs_revoke ( } -enum TALER_ErrorCode -TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh, - const struct TALER_CsPubHashP *h_cs, - const struct TALER_CsNonce *nonce, - struct TALER_DenominationCSPublicRPairP *crp) +/** + * Ask the helper to derive R using the @a nonce and denomination key + * associated with @a h_cs. + * + * This operation will block until the R has been obtained. Should + * this process receive a signal (that is not ignored) while the operation is + * pending, the operation will fail. Note that the helper may still believe + * that it created the signature. Thus, signals may result in a small + * differences in the signature counters. Retrying in this case may work. + * + * @param dh helper to process connection + * @param h_cs hash of the CS public key to revoke + * @param nonce witdhraw nonce + * @param for_melt true if the HKDF for melt should be used + * @param[out] crp set to the pair of R values + * @return set to the error code (or #TALER_EC_NONE on success) + */ +static enum TALER_ErrorCode +helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh, + const struct TALER_CsPubHashP *h_cs, + const struct TALER_CsNonce *nonce, + bool for_melt, + struct TALER_DenominationCSPublicRPairP *crp) { enum TALER_ErrorCode ec = TALER_EC_INVALID; @@ -630,7 +696,7 @@ TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh, struct TALER_CRYPTO_CsRDeriveRequest rdr = { .header.size = htons (sizeof (rdr)), .header.type = htons (TALER_HELPER_CS_MT_REQ_RDERIVE), - .reserved = htonl (0), + .for_melt = htonl (for_melt ? 1 : 0), .h_cs = *h_cs, .nonce = *nonce }; @@ -786,6 +852,36 @@ more: } +enum TALER_ErrorCode +TALER_CRYPTO_helper_cs_r_derive_withdraw ( + struct TALER_CRYPTO_CsDenominationHelper *dh, + const struct TALER_CsPubHashP *h_cs, + const struct TALER_CsNonce *nonce, + struct TALER_DenominationCSPublicRPairP *crp) +{ + return helper_cs_r_derive (dh, + h_cs, + nonce, + false, + crp); +} + + +enum TALER_ErrorCode +TALER_CRYPTO_helper_cs_r_derive_melt ( + struct TALER_CRYPTO_CsDenominationHelper *dh, + const struct TALER_CsPubHashP *h_cs, + const struct TALER_CsNonce *nonce, + struct TALER_DenominationCSPublicRPairP *crp) +{ + return helper_cs_r_derive (dh, + h_cs, + nonce, + true, + crp); +} + + void TALER_CRYPTO_helper_cs_disconnect ( struct TALER_CRYPTO_CsDenominationHelper *dh) diff --git a/src/util/denom.c b/src/util/denom.c index 7afc7f408..86c83d7cf 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -85,6 +85,7 @@ TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv, enum GNUNET_GenericReturnValue TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, const struct TALER_DenominationPrivateKey *denom_priv, + bool for_melt, const struct TALER_BlindedPlanchet *blinded_planchet) { memset (denom_sig, @@ -119,6 +120,7 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, 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 = diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c index 6e4e163b2..33167c8ea 100644 --- a/src/util/taler-exchange-secmod-cs.c +++ b/src/util/taler-exchange-secmod-cs.c @@ -283,6 +283,7 @@ handle_sign_request (struct TES_Client *client, struct GNUNET_CRYPTO_CsRSecret r[2]; struct TALER_BlindedDenominationCsSignAnswer cs_answer; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + bool for_melt; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); dk = GNUNET_CONTAINER_multihashmap_get (keys, @@ -318,7 +319,7 @@ handle_sign_request (struct TES_Client *client, return TES_transmit (client->csock, &sf.header); } - + for_melt = (0 != ntohl (sr->for_melt)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received request to sign over bytes with key %s\n", GNUNET_h2s (&sr->h_cs.hash)); @@ -326,6 +327,7 @@ handle_sign_request (struct TES_Client *client, dk->rc++; GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce, + for_melt ? "rm" : "rw", &dk->denom_priv, r); cs_answer.b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv, @@ -552,6 +554,7 @@ handle_r_derive_request (struct TES_Client *client, struct TALER_DenominationCSPrivateRPairP r_priv; struct TALER_DenominationCSPublicRPairP r_pub; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + bool for_melt; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); dk = GNUNET_CONTAINER_multihashmap_get (keys, @@ -587,7 +590,7 @@ handle_r_derive_request (struct TES_Client *client, return TES_transmit (client->csock, &rdf.header); } - + for_melt = (0 != ntohl (rdr->for_melt)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received request to derive R with key %s\n", GNUNET_h2s (&rdr->h_cs.hash)); @@ -595,10 +598,13 @@ handle_r_derive_request (struct TES_Client *client, dk->rc++; GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_CRYPTO_cs_r_derive (&rdr->nonce.nonce, + for_melt ? "rm" : "rw", &dk->denom_priv, r_priv.r); - GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[0], &r_pub.r_pub[0]); - GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[1], &r_pub.r_pub[1]); + GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[0], + &r_pub.r_pub[0]); + GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[1], + &r_pub.r_pub[1]); GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_assert (dk->rc > 0); dk->rc--; diff --git a/src/util/taler-exchange-secmod-cs.h b/src/util/taler-exchange-secmod-cs.h index c090e5cd1..c71c3b9af 100644 --- a/src/util/taler-exchange-secmod-cs.h +++ b/src/util/taler-exchange-secmod-cs.h @@ -122,9 +122,9 @@ struct TALER_CRYPTO_CsSignRequest struct GNUNET_MessageHeader header; /** - * For now, always zero. + * 0 for withdraw, 1 for melt, in NBO. */ - uint32_t reserved; + uint32_t for_melt; /** * Hash of the public key of the CS key to use for the signature. @@ -150,9 +150,9 @@ struct TALER_CRYPTO_CsRDeriveRequest struct GNUNET_MessageHeader header; /** - * For now, always zero. + * 0 for withdraw, 1 for melt, in NBO. */ - uint32_t reserved; + uint32_t for_melt; /** * Hash of the public key of the CS key to use for the derivation. diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c index d85dad609..35b964021 100644 --- a/src/util/test_crypto.c +++ b/src/util/test_crypto.c @@ -158,6 +158,7 @@ test_planchets_rsa (void) GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&blind_sig, &dk_priv, + false, &pd.blinded_planchet)); TALER_planchet_detail_free (&pd); GNUNET_assert (GNUNET_OK == @@ -201,6 +202,7 @@ derive_r_public ( 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], @@ -264,6 +266,7 @@ test_planchets_cs (void) GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&blind_sig, &dk_priv, + false, &pd.blinded_planchet)); TALER_planchet_detail_free (&pd); GNUNET_assert (GNUNET_OK == diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c index b6b72e2e1..c2708353d 100644 --- a/src/util/test_helper_cs.c +++ b/src/util/test_helper_cs.c @@ -289,7 +289,7 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) "Requesting R derivation with key %s\n", GNUNET_h2s (&keys[i].h_cs.hash)); alg_values.cipher = TALER_DENOMINATION_CS; - ec = TALER_CRYPTO_helper_cs_r_derive ( + ec = TALER_CRYPTO_helper_cs_r_derive_withdraw ( dh, &keys[i].h_cs, &pd.blinded_planchet.details.cs_blinded_planchet.nonce, @@ -381,10 +381,10 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &nonce, sizeof (nonce)); - ec = TALER_CRYPTO_helper_cs_r_derive (dh, - &rnd, - &nonce, - &crp); + ec = TALER_CRYPTO_helper_cs_r_derive_withdraw (dh, + &rnd, + &nonce, + &crp); if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) { GNUNET_break (0); @@ -431,12 +431,13 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) &pd.blinded_planchet.details. cs_blinded_planchet.nonce); alg_values.cipher = TALER_DENOMINATION_CS; - ec = TALER_CRYPTO_helper_cs_r_derive (dh, - &keys[i].h_cs, - &pd.blinded_planchet. - details. - cs_blinded_planchet.nonce, - &alg_values.details.cs_values); + ec = TALER_CRYPTO_helper_cs_r_derive_withdraw ( + dh, + &keys[i].h_cs, + &pd.blinded_planchet. + details. + cs_blinded_planchet.nonce, + &alg_values.details.cs_values); if (TALER_EC_NONE != ec) continue; TALER_planchet_setup_coin_priv (&ps, @@ -457,11 +458,12 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting signature with key %s\n", GNUNET_h2s (&keys[i].h_cs.hash)); - ec = TALER_CRYPTO_helper_cs_sign (dh, - &keys[i].h_cs, - &pd.blinded_planchet.details. - cs_blinded_planchet, - &ds); + ec = TALER_CRYPTO_helper_cs_sign_withdraw ( + dh, + &keys[i].h_cs, + &pd.blinded_planchet.details. + cs_blinded_planchet, + &ds); } switch (ec) { @@ -556,11 +558,11 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh) &c_hash, &pd)); - ec = TALER_CRYPTO_helper_cs_sign (dh, - &rnd, - &pd.blinded_planchet.details. - cs_blinded_planchet, - &ds); + ec = TALER_CRYPTO_helper_cs_sign_withdraw ( + dh, + &rnd, + &pd.blinded_planchet.details.cs_blinded_planchet, + &ds); if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec) { if (TALER_EC_NONE == ec) @@ -622,12 +624,13 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, &pd.blinded_planchet.details. cs_blinded_planchet.nonce); alg_values.cipher = TALER_DENOMINATION_CS; - ec = TALER_CRYPTO_helper_cs_r_derive (dh, - &keys[i].h_cs, - &pd.blinded_planchet. - details. - cs_blinded_planchet.nonce, - &alg_values.details.cs_values); + ec = TALER_CRYPTO_helper_cs_r_derive_melt ( + dh, + &keys[i].h_cs, + &pd.blinded_planchet. + details. + cs_blinded_planchet.nonce, + &alg_values.details.cs_values); if (TALER_EC_NONE != ec) continue; TALER_planchet_setup_coin_priv (&ps, @@ -650,11 +653,12 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh, struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get (); struct GNUNET_TIME_Relative delay; - ec = TALER_CRYPTO_helper_cs_sign (dh, - &keys[i].h_cs, - &pd.blinded_planchet.details. - cs_blinded_planchet, - &ds); + ec = TALER_CRYPTO_helper_cs_sign_melt ( + dh, + &keys[i].h_cs, + &pd.blinded_planchet.details. + cs_blinded_planchet, + &ds); if (TALER_EC_NONE != ec) break; delay = GNUNET_TIME_absolute_get_duration (start); |