donau_crypto.c (9023B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file util/donau_crypto.c 18 * @brief Cryptographic utility functions 19 * @author Lukas Matyja 20 */ 21 #include "donau_config.h" 22 #include <taler/taler_util.h> 23 #include "donau_util.h" 24 #include <gcrypt.h> 25 26 GNUNET_NETWORK_STRUCT_BEGIN 27 /** 28 * Structure we hash to compute the group key for 29 * a donation unit group. 30 */ 31 struct DonationUnitGroupP 32 { 33 /** 34 * Value of coins in this donation unit group. 35 */ 36 struct TALER_AmountNBO value; 37 38 /** 39 * Cipher used for the donation unit, in NBO. 40 */ 41 uint32_t cipher GNUNET_PACKED; 42 }; 43 GNUNET_NETWORK_STRUCT_END 44 45 46 void 47 DONAU_donation_unit_group_get_key ( 48 const struct DONAU_DonationUnitGroup *dg, 49 struct GNUNET_HashCode *key) 50 { 51 struct DonationUnitGroupP dgp = { 52 .cipher = htonl (dg->cipher) 53 }; 54 55 TALER_amount_hton (&dgp.value, 56 &dg->value); 57 GNUNET_CRYPTO_hash (&dgp, 58 sizeof (dgp), 59 key); 60 } 61 62 63 int 64 DONAU_donation_unit_pub_cmp ( 65 const struct DONAU_DonationUnitPublicKey *donation_unit1, 66 const struct DONAU_DonationUnitPublicKey *donation_unit2) 67 { 68 if (donation_unit1->bsign_pub_key->cipher != 69 donation_unit2->bsign_pub_key->cipher) 70 return (donation_unit1->bsign_pub_key->cipher > 71 donation_unit2->bsign_pub_key->cipher) ? 1 : -1; 72 return GNUNET_CRYPTO_bsign_pub_cmp (donation_unit1->bsign_pub_key, 73 donation_unit2->bsign_pub_key); 74 } 75 76 77 void 78 DONAU_donation_unit_pub_deep_copy ( 79 struct DONAU_DonationUnitPublicKey *donation_unit_dst, 80 const struct DONAU_DonationUnitPublicKey *donation_unit_src) 81 { 82 donation_unit_dst->bsign_pub_key 83 = GNUNET_CRYPTO_bsign_pub_incref (donation_unit_src->bsign_pub_key); 84 } 85 86 87 void 88 DONAU_donation_unit_pub_free ( 89 struct DONAU_DonationUnitPublicKey *donation_unit_pub) 90 { 91 if (NULL != donation_unit_pub->bsign_pub_key) 92 { 93 GNUNET_CRYPTO_blind_sign_pub_decref (donation_unit_pub->bsign_pub_key); 94 donation_unit_pub->bsign_pub_key = NULL; 95 } 96 } 97 98 99 void 100 DONAU_blinded_donation_unit_sig_free ( 101 struct DONAU_BlindedDonationUnitSignature *du_sig) 102 { 103 if (NULL != du_sig->blinded_sig) 104 { 105 GNUNET_CRYPTO_blinded_sig_decref (du_sig->blinded_sig); 106 du_sig->blinded_sig = NULL; 107 } 108 } 109 110 111 void 112 DONAU_donation_unit_pub_hash ( 113 const struct DONAU_DonationUnitPublicKey *donation_unit_pub, 114 struct DONAU_DonationUnitHashP *donation_unit_hash 115 ) 116 { 117 struct GNUNET_CRYPTO_BlindSignPublicKey *bsp 118 = donation_unit_pub->bsign_pub_key; 119 120 switch (bsp->cipher) 121 { 122 case GNUNET_CRYPTO_BSA_RSA: 123 /* Important: this MUST match the way the RSA-secmod does the 124 hashing of the public keys (see donau-httpd_keys.c) */ 125 GNUNET_CRYPTO_rsa_public_key_hash (bsp->details.rsa_public_key, 126 &donation_unit_hash->hash); 127 break; 128 case GNUNET_CRYPTO_BSA_CS: 129 /* Important: this MUST match the way the CS-secmod does the 130 hashing of the public keys (see donau-httpd_keys.c) */ 131 GNUNET_CRYPTO_hash (&bsp->details.cs_public_key, 132 sizeof(bsp->details.cs_public_key), 133 &donation_unit_hash->hash); 134 break; 135 default: 136 GNUNET_assert (0); 137 } 138 } 139 140 141 void 142 DONAU_unique_donor_id_hash ( 143 const struct DONAU_HashDonorTaxId *h_donor_tax_id, 144 const struct DONAU_UniqueDonorIdentifierNonce *nonce, 145 struct DONAU_UniqueDonorIdentifierHashP *h_udi) 146 { 147 struct GNUNET_HashContext *hash_context; 148 149 hash_context = GNUNET_CRYPTO_hash_context_start (); 150 GNUNET_CRYPTO_hash_context_read ( 151 hash_context, 152 h_donor_tax_id, 153 sizeof(struct DONAU_HashDonorTaxId)); 154 GNUNET_CRYPTO_hash_context_read ( 155 hash_context, 156 nonce, 157 sizeof(struct DONAU_UniqueDonorIdentifierNonce)); 158 GNUNET_CRYPTO_hash_context_finish ( 159 hash_context, 160 &h_udi->hash); 161 } 162 163 164 enum GNUNET_GenericReturnValue 165 DONAU_donation_receipt_verify ( 166 const struct DONAU_DonationUnitPublicKey *donation_unit_pub, 167 const struct DONAU_UniqueDonorIdentifierHashP *h_udi, 168 const struct DONAU_DonationUnitSignature *donation_unit_sig) 169 { 170 return GNUNET_CRYPTO_blind_sig_verify (donation_unit_pub->bsign_pub_key, 171 donation_unit_sig->unblinded_sig, 172 h_udi, 173 sizeof (*h_udi)); 174 } 175 176 177 enum GNUNET_GenericReturnValue 178 DONAU_donation_unit_blind ( 179 const struct DONAU_DonationUnitPublicKey *du_pub, 180 const union GNUNET_CRYPTO_BlindingSecretP *budi_secret, 181 const union GNUNET_CRYPTO_BlindSessionNonce *cs_nonce, 182 const struct DONAU_UniqueDonorIdentifierNonce *udi_nonce,// message 183 const struct DONAU_HashDonorTaxId *h_tax_id, // message 184 const struct DONAU_BatchIssueValues *alg_values, 185 struct DONAU_UniqueDonorIdentifierHashP *udi_hash, 186 struct DONAU_BlindedUniqueDonorIdentifier *budi) 187 { 188 DONAU_unique_donor_id_hash ( 189 h_tax_id, 190 udi_nonce, 191 udi_hash); 192 193 budi->blinded_message 194 = GNUNET_CRYPTO_message_blind_to_sign (du_pub->bsign_pub_key, 195 budi_secret, 196 cs_nonce, 197 udi_hash, 198 sizeof (*udi_hash), 199 alg_values->blinding_inputs); 200 if (NULL == budi->blinded_message) 201 return GNUNET_SYSERR; 202 return GNUNET_OK; 203 } 204 205 206 enum GNUNET_GenericReturnValue 207 DONAU_donation_unit_sig_unblind ( 208 struct DONAU_DonationUnitSignature *du_sig, 209 const struct DONAU_BlindedDonationUnitSignature *blind_du_sig, 210 const union GNUNET_CRYPTO_BlindingSecretP *budi_secret, 211 const struct DONAU_UniqueDonorIdentifierHashP *udi_hash, 212 const struct DONAU_BatchIssueValues *alg_values, 213 const struct DONAU_DonationUnitPublicKey *du_pub) 214 { 215 du_sig->unblinded_sig 216 = GNUNET_CRYPTO_blind_sig_unblind (blind_du_sig->blinded_sig, 217 budi_secret, 218 udi_hash, 219 sizeof (*udi_hash), 220 alg_values->blinding_inputs, 221 du_pub->bsign_pub_key); 222 if (NULL == du_sig->unblinded_sig) 223 { 224 GNUNET_break_op (0); 225 return GNUNET_SYSERR; 226 } 227 return GNUNET_OK; 228 } 229 230 231 void 232 DONAU_budi_secret_create ( 233 const struct DONAU_BudiMasterSecretP *ps, 234 const struct DONAU_BatchIssueValues *alg_values, 235 union GNUNET_CRYPTO_BlindingSecretP *bks) 236 { 237 const struct GNUNET_CRYPTO_BlindingInputValues *bi = 238 alg_values->blinding_inputs; 239 240 switch (bi->cipher) 241 { 242 case GNUNET_CRYPTO_BSA_INVALID: 243 GNUNET_break (0); 244 return; 245 case GNUNET_CRYPTO_BSA_RSA: 246 GNUNET_assert (GNUNET_YES == 247 GNUNET_CRYPTO_kdf (&bks->rsa_bks, 248 sizeof (bks->rsa_bks), 249 "bks", 250 strlen ("bks"), 251 ps, 252 sizeof(*ps), 253 NULL, 254 0)); 255 return; 256 case GNUNET_CRYPTO_BSA_CS: 257 GNUNET_assert (GNUNET_YES == 258 GNUNET_CRYPTO_kdf (&bks->nonce, 259 sizeof (bks->nonce), 260 "bseed", 261 strlen ("bseed"), 262 ps, 263 sizeof(*ps), 264 &bi->details.cs_values, 265 sizeof(bi->details.cs_values), 266 NULL, 267 0)); 268 return; 269 } 270 GNUNET_assert (0); 271 } 272 273 274 const struct DONAU_BatchIssueValues * 275 DONAU_donation_unit_ewv_rsa_singleton () 276 { 277 static struct GNUNET_CRYPTO_BlindingInputValues bi = { 278 .cipher = GNUNET_CRYPTO_BSA_RSA 279 }; 280 static struct DONAU_BatchIssueValues alg_values = { 281 .blinding_inputs = &bi 282 }; 283 return &alg_values; 284 } 285 286 287 void 288 DONAU_donation_unit_ewv_copy (struct DONAU_BatchIssueValues *bi_dst, 289 const struct DONAU_BatchIssueValues *bi_src) 290 { 291 if (bi_src == DONAU_donation_unit_ewv_rsa_singleton ()) 292 { 293 *bi_dst = *bi_src; 294 return; 295 } 296 bi_dst->blinding_inputs 297 = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs); 298 }