anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

anastasis_crypto_lib.h (17567B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2020, 2021 Anastasis SARL
      4 
      5   Anastasis 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   Anastasis 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   Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file include/anastasis_crypto_lib.h
     18  * @brief anastasis crypto api
     19  * @author Christian Grothoff
     20  * @author Dominik Meister
     21  * @author Dennis Neufeld
     22  */
     23 #include <jansson.h>
     24 #include <gnunet/gnunet_util_lib.h>
     25 
     26 
     27 /**
     28  * Server to client: this is the policy version.
     29  */
     30 #define ANASTASIS_HTTP_HEADER_POLICY_VERSION "Anastasis-Version"
     31 
     32 /**
     33  * Server to client: this is the policy expiration time.
     34  */
     35 #define ANASTASIS_HTTP_HEADER_POLICY_EXPIRATION "Anastasis-Policy-Expiration"
     36 
     37 /**
     38  * Client to server: use this to decrypt the truth.
     39  */
     40 #define ANASTASIS_HTTP_HEADER_TRUTH_DECRYPTION_KEY \
     41         "Anastasis-Truth-Decryption-Key"
     42 
     43 /**
     44  * Client to server: please store this meta data.
     45  */
     46 #define ANASTASIS_HTTP_HEADER_POLICY_META_DATA "Anastasis-Policy-Meta-Data"
     47 
     48 
     49 /**
     50  * Client to server: I paid using this payment secret.
     51  */
     52 #define ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER "Anastasis-Payment-Identifier"
     53 
     54 /**
     55  * Client to server: I am authorized to update this policy, or
     56  * server to client: I prove this is a valid policy.
     57  */
     58 #define ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE "Anastasis-Policy-Signature"
     59 
     60 /**
     61  * Server to client: Taler Payto-URI.
     62  */
     63 #define ANASTASIS_HTTP_HEADER_TALER "Taler"
     64 
     65 
     66 GNUNET_NETWORK_STRUCT_BEGIN
     67 
     68 /**
     69  * An EdDSA public key that is used to identify a user's account.
     70  */
     71 struct ANASTASIS_CRYPTO_AccountPublicKeyP
     72 {
     73   struct GNUNET_CRYPTO_EddsaPublicKey pub;
     74 };
     75 
     76 
     77 /**
     78  * An EdDSA private key that is used to identify a user's account.
     79  */
     80 struct ANASTASIS_CRYPTO_AccountPrivateKeyP
     81 {
     82   struct GNUNET_CRYPTO_EddsaPrivateKey priv;
     83 };
     84 
     85 
     86 /**
     87  * A UUID that is used to identify a truth object
     88  */
     89 struct ANASTASIS_CRYPTO_TruthUUIDP
     90 {
     91   struct GNUNET_ShortHashCode uuid;
     92 };
     93 
     94 
     95 /**
     96  * Specifies a TruthKey which is used to decrypt the Truth stored by the user.
     97  */
     98 struct ANASTASIS_CRYPTO_TruthKeyP
     99 {
    100   struct GNUNET_HashCode key GNUNET_PACKED;
    101 };
    102 
    103 
    104 /**
    105  * Specifies a salt value used to encrypt the master public key.
    106  */
    107 struct ANASTASIS_CRYPTO_MasterSaltP
    108 {
    109   struct GNUNET_HashCode salt GNUNET_PACKED;
    110 };
    111 
    112 
    113 /**
    114  * Specifies a salt value used for salting the answer to a security question.
    115  */
    116 struct ANASTASIS_CRYPTO_QuestionSaltP
    117 {
    118   struct GNUNET_CRYPTO_PowSalt pow_salt;
    119 };
    120 
    121 
    122 /**
    123  * Specifies a salt value provided by an Anastasis provider,
    124  * used for deriving the provider-specific user ID.
    125  */
    126 struct ANASTASIS_CRYPTO_ProviderSaltP
    127 {
    128   struct GNUNET_CRYPTO_PowSalt salt;
    129 };
    130 
    131 
    132 /**
    133  * Specifies a policy key which is used to decrypt the master key
    134  */
    135 struct ANASTASIS_CRYPTO_PolicyKeyP
    136 {
    137   struct GNUNET_HashCode key GNUNET_PACKED;
    138 };
    139 
    140 
    141 /**
    142  * Nonce used for encryption, 24 bytes.
    143  */
    144 struct ANASTASIS_CRYPTO_NonceP
    145 {
    146   uint8_t nonce[crypto_secretbox_NONCEBYTES];
    147 };
    148 
    149 
    150 /**
    151  * Header that is prepended to a ciphertext, consisting of nonce and MAC.
    152  */
    153 struct ANASTASIS_CRYPTO_CiphertextHeaderP
    154 {
    155   uint8_t header[crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES];
    156 };
    157 
    158 
    159 /**
    160  * Specifies a key used for symmetric encryption, 32 bytes.
    161  */
    162 struct ANASTASIS_CRYPTO_SymKeyP
    163 {
    164   uint32_t key[8];
    165 };
    166 
    167 
    168 /**
    169  * Specifies a Key Share from an escrow provider, the combined
    170  * keyshares generate the EscrowMasterKey which is used to decrypt the
    171  * Secret from the user.
    172  */
    173 struct ANASTASIS_CRYPTO_KeyShareP
    174 {
    175   uint32_t key[8];
    176 };
    177 
    178 
    179 /**
    180  * Specifies an encrypted KeyShare
    181  */
    182 struct ANASTASIS_CRYPTO_EncryptedKeyShareP
    183 {
    184   /**
    185    * Ciphertext.
    186    */
    187   struct ANASTASIS_CRYPTO_CiphertextHeaderP header;
    188 
    189   /**
    190    * The actual key share, encrypted.
    191    */
    192   struct ANASTASIS_CRYPTO_KeyShareP keyshare;
    193 };
    194 
    195 
    196 /**
    197  * The escrow master key is the key used to encrypt the user secret (MasterKey).
    198  */
    199 struct ANASTASIS_CRYPTO_EscrowMasterKeyP
    200 {
    201   uint32_t key[8];
    202 };
    203 
    204 
    205 /**
    206  * The user identifier consists of user information and the server salt. It is used as
    207  * entropy source to generate the account public key and the encryption keys.
    208  */
    209 struct ANASTASIS_CRYPTO_UserIdentifierP
    210 {
    211   struct GNUNET_HashCode hash GNUNET_PACKED;
    212 };
    213 
    214 
    215 /**
    216  * Random identifier used to later charge a payment.
    217  */
    218 struct ANASTASIS_PaymentSecretP
    219 {
    220   uint32_t id[8];
    221 };
    222 
    223 
    224 /**
    225  * Data signed by the account public key of a sync client to
    226  * authorize the upload of the backup.
    227  */
    228 struct ANASTASIS_UploadSignaturePS
    229 {
    230   /**
    231    * Set to #TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD.
    232    */
    233   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    234 
    235   /**
    236    * Hash of the new backup.
    237    */
    238   struct GNUNET_HashCode new_recovery_data_hash;
    239 
    240 };
    241 
    242 
    243 /**
    244  * Signature made with an account's public key.
    245  */
    246 struct ANASTASIS_AccountSignatureP
    247 {
    248   /**
    249    * We use EdDSA.
    250    */
    251   struct GNUNET_CRYPTO_EddsaSignature eddsa_sig;
    252 };
    253 
    254 
    255 GNUNET_NETWORK_STRUCT_END
    256 
    257 /**
    258  * Result of encrypting the core secret.
    259  */
    260 struct ANASTASIS_CoreSecretEncryptionResult
    261 {
    262   /**
    263    * Encrypted core secret.
    264    */
    265   void *enc_core_secret;
    266 
    267   /**
    268    * Size of the encrypted core secret.
    269    */
    270   size_t enc_core_secret_size;
    271 
    272   /**
    273    * Array of encrypted master keys.  Each key is encrypted
    274    * to a different policy key.
    275    */
    276   void **enc_master_keys;
    277 
    278   /**
    279    * Sizes of the encrypted master keys.
    280    */
    281   size_t *enc_master_key_sizes;
    282 };
    283 
    284 
    285 /**
    286  * Hash a numerical answer to compute the hash value to be submitted
    287  * to the server for verification. Useful for PINs and SMS-TANs and
    288  * other numbers submitted for challenges.
    289  *
    290  * @param code the numeric value to hash
    291  * @param[out] hashed_code the resulting hash value to submit to the Anastasis server
    292  */
    293 void
    294 ANASTASIS_hash_answer (uint64_t code,
    295                        struct GNUNET_HashCode *hashed_code);
    296 
    297 
    298 /**
    299  * Creates the UserIdentifier, it is used as entropy source for the
    300  * encryption keys and for the public and private key for signing the
    301  * data.
    302  *
    303  * @param id_data JSON encoded data, which contains the raw user secret
    304  * @param provider_salt salt from the server (escrow provider)
    305  * @param[out] id reference to the id which was created
    306  */
    307 void
    308 ANASTASIS_CRYPTO_user_identifier_derive (
    309   const json_t *id_data,
    310   const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
    311   struct ANASTASIS_CRYPTO_UserIdentifierP *id);
    312 
    313 
    314 /**
    315  * Generates the eddsa public Key used as the account identifier on the providers
    316  *
    317  * @param id holds a hashed user secret which is used as entropy source for the public key generation
    318  * @param[out] pub_key handle for the generated public key
    319  */
    320 void
    321 ANASTASIS_CRYPTO_account_public_key_derive (
    322   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    323   struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub_key);
    324 
    325 
    326 /**
    327  * //FIXME combine these two
    328  * Generates the eddsa public Key used as the account identifier on the providers
    329  *
    330  * @param id holds a hashed user secret which is used as entropy source for the public key generation
    331  * @param[out] priv_key handle for the generated private key
    332  */
    333 void
    334 ANASTASIS_CRYPTO_account_private_key_derive (
    335   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    336   struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv_key);
    337 
    338 
    339 /**
    340  * Hash @a answer to security question with @a salt and @a uuid to compute
    341  * @a result that would be sent to the service for authorization.
    342  *
    343  * @param answer human answer to a security question
    344  * @param uuid the truth UUID (known to the service)
    345  * @param salt random salt value, unknown to the service
    346  * @param[out] result where to write the resulting hash
    347  */
    348 void
    349 ANASTASIS_CRYPTO_secure_answer_hash (
    350   const char *answer,
    351   const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
    352   const struct ANASTASIS_CRYPTO_QuestionSaltP *salt,
    353   struct GNUNET_HashCode *result);
    354 
    355 
    356 /**
    357  * Encrypt and signs the recovery document, the recovery
    358  * document is encrypted with a derivation from the user identifier
    359  * and the salt "erd".
    360  *
    361  * @param id Hashed User input, used for the generation of the encryption key
    362  * @param rec_doc contains the recovery document as raw data
    363  * @param rd_size defines the size of the recovery document inside data
    364  * @param[out] enc_rec_doc return from the result, which contains the encrypted recovery document
    365  *            and the nonce and iv used for the encryption as Additional Data
    366  * @param[out] erd_size size of the result
    367  */
    368 void
    369 ANASTASIS_CRYPTO_recovery_document_encrypt (
    370   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    371   const void *rec_doc,
    372   size_t rd_size,
    373   void **enc_rec_doc,
    374   size_t *erd_size);
    375 
    376 
    377 /**
    378  * Decrypts the recovery document, the decryption key is generated with
    379  * the user identifier provided by the user and the salt "erd". The nonce and IV used for the encryption
    380  * are the first 48 bytes of the data.
    381  *
    382  * @param id Hashed User input, used for the generation of the encryption key
    383  * @param enc_rec_doc contains the encrypted recovery document and the nonce and iv used for the encryption.
    384  * @param erd_size size of the data
    385  * @param[out] rec_doc return from the result, which contains the encrypted recovery document
    386  *            and the nonce and iv used for the encryption as Additional Data
    387  * @param[out] rd_size size of the result
    388  */
    389 void
    390 ANASTASIS_CRYPTO_recovery_document_decrypt (
    391   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    392   const void *enc_rec_doc,
    393   size_t erd_size,
    394   void **rec_doc,
    395   size_t *rd_size);
    396 
    397 
    398 /**
    399  * Encrypt recovery document meta data.
    400  *
    401  * @param id Hashed User input, used for the generation of the encryption key
    402  * @param meta_data contains the recovery document meta data
    403  * @param meta_data_size number of bytes in @a meta_data
    404  * @param[out] enc_meta_data set to the encrypted meta data
    405  * @param[out] enc_meta_data_size size of the result
    406  */
    407 void
    408 ANASTASIS_CRYPTO_recovery_metadata_encrypt (
    409   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    410   const void *meta_data,
    411   size_t meta_data_size,
    412   void **enc_meta_data,
    413   size_t *enc_meta_data_size);
    414 
    415 
    416 /**
    417  * Decrypts the recovery meta data.
    418  *
    419  * @param id Hashed User input, used for the generation of the decryption key
    420  * @param enc_meta_data encrypted meta data
    421  * @param enc_meta_data_size number of bytes in @a enc_meta_data
    422  * @param[out] meta_data decrypted meta data
    423  * @param[out] meta_data_size size of the result in @a meta_data
    424  * @return #GNUNET_OK on success, #GNUNET_NO if the authentication tag
    425  *          was wrong
    426  */
    427 enum GNUNET_GenericReturnValue
    428 ANASTASIS_CRYPTO_recovery_metadata_decrypt (
    429   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    430   const void *enc_meta_data,
    431   size_t enc_meta_data_size,
    432   void **meta_data,
    433   size_t *meta_data_size);
    434 
    435 
    436 /**
    437  * Encrypts a keyshare with a key generated with the user identification as entropy and the salt "eks".
    438  *
    439  * @param key_share the key share which is afterwards encrypted
    440  * @param id the user identification which is the entropy source for the key generation
    441  * @param xsalt answer to security question, otherwise NULL; used as extra salt in KDF
    442  * @param[out] enc_key_share holds the encrypted share, the first 48 Bytes are the used nonce and tag
    443  */
    444 void
    445 ANASTASIS_CRYPTO_keyshare_encrypt (
    446   const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
    447   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    448   const char *xsalt,
    449   struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share);
    450 
    451 
    452 /**
    453  * Decrypts a keyshare with a key generated with the user identification as entropy and the salt "eks".
    454  *
    455  * @param enc_key_share holds the encrypted share, the first 48 Bytes are the used nonce and tag
    456  * @param id the user identification which is the entropy source for the key generation
    457  * @param xsalt answer to security question, otherwise NULL; used as extra salt in KDF
    458  * @param[out] key_share the result of decryption
    459  */
    460 void
    461 ANASTASIS_CRYPTO_keyshare_decrypt (
    462   const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share,
    463   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
    464   const char *xsalt,
    465   struct ANASTASIS_CRYPTO_KeyShareP *key_share);
    466 
    467 
    468 /**
    469  * Encrypts the truth data which contains the hashed answer or the
    470  * phone number.  It is encrypted with xsalsa20-poly1305, the key is generated
    471  * with the user identification as entropy source and the salt "ect".
    472  *
    473  * @param nonce value to use for the nonce
    474  * @param truth_enc_key master key used for encryption of the truth (see interface EscrowMethod)
    475  * @param truth truth which will be encrypted
    476  * @param truth_size size of the truth
    477  * @param[out] enc_truth return from the result, which contains the encrypted truth
    478  *            and the nonce and iv used for the encryption as Additional Data
    479  * @param[out] ect_size size of the result
    480  */
    481 void
    482 ANASTASIS_CRYPTO_truth_encrypt (
    483   const struct ANASTASIS_CRYPTO_NonceP *nonce,
    484   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key,
    485   const void *truth,
    486   size_t truth_size,
    487   void **enc_truth,
    488   size_t *ect_size);
    489 
    490 
    491 /**
    492  * Decrypts the truth data which contains the hashed answer or the phone number..
    493  * It is decrypted with xsalsa20-poly1305, the key is generated with the user identification as
    494  * entropy source and the salt "ect".
    495  *
    496  * @param truth_enc_key master key used for encryption of the truth (see interface EscrowMethod)
    497  * @param enc_truth truth holds the encrypted truth which will be decrypted
    498  * @param ect_size size of the truth data
    499  * @param truth return from the result, which contains the truth
    500  * @param truth_size size of the result
    501  */
    502 void
    503 ANASTASIS_CRYPTO_truth_decrypt (
    504   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key,
    505   const void *enc_truth,
    506   size_t ect_size,
    507   void **truth,
    508   size_t *truth_size);
    509 
    510 
    511 /**
    512  * A key share is randomly generated, one key share is generated for every
    513  * truth a policy contains.
    514  *
    515  * @param[out] key_share reference to the created key share.
    516  */
    517 void
    518 ANASTASIS_CRYPTO_keyshare_create (
    519   struct ANASTASIS_CRYPTO_KeyShareP *key_share);
    520 
    521 
    522 /**
    523  * Once per policy a policy key is derived. The policy key consists of
    524  * multiple key shares which are combined and hashed.
    525  *
    526  * @param key_shares list of key shares which are combined
    527  * @param keyshare_length amount of key shares inside the array
    528  * @param salt salt value
    529  * @param[out] policy_key reference to the created key
    530  */
    531 void
    532 ANASTASIS_CRYPTO_policy_key_derive (
    533   const struct ANASTASIS_CRYPTO_KeyShareP *key_shares,
    534   unsigned int keyshare_length,
    535   const struct ANASTASIS_CRYPTO_MasterSaltP *salt,
    536   struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key);
    537 
    538 
    539 /**
    540  * The core secret is the user provided secret which will be saved with Anastasis.
    541  * The secret will be encrypted with the master key, the master key is a random key which will
    542  * be generated. The master key afterwards will be encrypted with the different policy keys.
    543  * Encryption is performed with xsalsa20-poly1305.
    544  *
    545  * @param policy_keys an array of policy keys which are used to encrypt the master key
    546  * @param policy_keys_length defines the amount of policy keys and also the amount of encrypted master keys
    547  * @param core_secret the user provided core secret which is secured by anastasis
    548  * @param core_secret_size the size of the core secret
    549  * @returns result of the encryption, must be freed with #ANASTASIS_CRYPTO_destroy_encrypted_core_secret
    550  */
    551 struct ANASTASIS_CoreSecretEncryptionResult *
    552 ANASTASIS_CRYPTO_core_secret_encrypt (
    553   const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
    554   unsigned int policy_keys_length,
    555   const void *core_secret,
    556   size_t core_secret_size);
    557 
    558 
    559 /**
    560  * Destroy a core secret encryption result.
    561  *
    562  * @param cser the result to destroy
    563  */
    564 void
    565 ANASTASIS_CRYPTO_destroy_encrypted_core_secret (
    566   struct ANASTASIS_CoreSecretEncryptionResult *cser);
    567 
    568 
    569 /**
    570  * Decrypts the core secret with the master key. First the master key is decrypted with the provided policy key.
    571  * Afterwards the core secret is encrypted with the master key. The core secret is returned.
    572  *
    573  * @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key
    574  * @param encrypted_master_key_size size of the encrypted master key
    575  * @param policy_key built policy key which will decrypt the master key
    576  * @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key
    577  * @param encrypted_core_secret_size size of the encrypted core secret
    578  * @param[out] core_secret decrypted core secret will be returned
    579  * @param[out] core_secret_size size of core secret
    580  */
    581 void
    582 ANASTASIS_CRYPTO_core_secret_recover (
    583   const void *encrypted_master_key,
    584   size_t encrypted_master_key_size,
    585   const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key,
    586   const void *encrypted_core_secret,
    587   size_t encrypted_core_secret_size,
    588   void **core_secret,
    589   size_t *core_secret_size);
    590 
    591 
    592 /**
    593  * Convert a @a uuid to a shortened, human-readable string
    594  * useful to show to users to identify the truth.
    595  * Note that the return value is in a global variable and
    596  * only valid until the next invocation of this function.
    597  *
    598  * @param uuid UUID to convert
    599  * @return string representation
    600  */
    601 const char *
    602 ANASTASIS_CRYPTO_uuid2s (const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid);