gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-anastasis] branch master updated: updates to spec


From: gnunet
Subject: [GNUnet-SVN] [taler-anastasis] branch master updated: updates to spec
Date: Thu, 03 Oct 2019 16:13:40 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new f7f0575  updates to spec
f7f0575 is described below

commit f7f057501c108816f1af8cb73ea0dcf560df5452
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Oct 3 16:12:24 2019 +0200

    updates to spec
---
 src/api/api-anastasis.rst               |  48 ++++++-------
 src/api/crypto-anastasis.rst            |  65 +++++++----------
 src/include/anastasis_database_plugin.h | 123 ++++++++++++++++++++++++++------
 3 files changed, 147 insertions(+), 89 deletions(-)

diff --git a/src/api/api-anastasis.rst b/src/api/api-anastasis.rst
index dc76b5a..0dc9823 100644
--- a/src/api/api-anastasis.rst
+++ b/src/api/api-anastasis.rst
@@ -46,21 +46,10 @@ The public account key is Crockford base32-encoded in the 
URI to identify the
 account, and used to sign requests.  These signatures are provided in base32
 encoding using the HTTP header "Anastasis-Account-Signature".
 
-A second ECDHE **encryption key** is also derived per account to encrypt
-information stored on the Anastasis server on behalf of the user.  The ECDHE
-private key is derived from the user's identifier via another computationally
-expensive cryptographic hash function H_2.  To encrypt some payload, another
-**ephemeral** ECDHE key is created (fresh for each encryption operation).  The
-ECDH of the encryption key and the ephemeral key is then given to an HKDF to
-derive a symmetric key and IV to encrypt the plaintext using AES-GCM as an
-AEAD, with the **account key** (in binary) being provided as associated data.
-The public ephemeral key and the GCM tag are then pre-pended to the resulting
-ciphertext and uploaded to the Anastasis server.  This is done whenever
-encrypted data is stored with the server.  The **salt** given to the HKDF is
-varied to indicate the context of the encryption operation (preventing the
-server from switching ciphertexts from the same account).  Below, we will
-specify the salt used for each encryption operation with the respective use of
-encryption in the protocol.
+Payloads are encrypted using AES-GCM with a symmetric key and IV derived from
+the identifier and a nonce.  The nonce and the GCM tag are then pre-pended to
+the resulting ciphertext and uploaded to the Anastasis server.  This is done
+whenever encrypted data is stored with the server.
 
 The **core secret** of the user is encrypted using a symmetric **master key**.
 Recovering the master key requires the user to satisfy a particular
@@ -169,8 +158,8 @@ public key using the Crockford base32-encoding.
   Get the customer's policy and encrypted master key share data.  If "version"
   is not specified, returns the latest available version.  If
   "version" is specified, returns the policy with the respective
-  "version".  The response must begin with an ephemeral ECDHE public
-  key and continue with an AES-GCM tag and ciphertext.  Once decrypted, the
+  "version".  The response must begin with the nonce and
+  an AES-GCM tag and continue with the ciphertext.  Once decrypted, the
   plaintext is expected to contain:
 
   * the escrow policy
@@ -208,8 +197,7 @@ public key using the Crockford base32-encoding.
 
   Upload a new version of the customer's policy and encrypted master key share 
data.
   If request has been seen before, the server should do nothing, and otherwise 
store the new version.
-  The body must begin with an ephemeral ECDHE public
-  key and continue with an AES-GCM tag and ciphertext.  The format
+  The body must begin with a nonce, an AES-GCM tag and continue with the 
ciphertext.  The format
   is the same as specified for the response of the GET method. The
   Anastasis server cannot validate the format, but MAY impose
   minimum and maximum size limits.
@@ -231,6 +219,8 @@ public key using the Crockford base32-encoding.
   :status 413 Request Entity Too Large:
     The upload is too large *or* too small. The response body may elaborate on 
the error.
 
+  FIXME: clarify which headers are from client and which from server (or 
both!).
+    
   *Anastasis-Version*: $NUMBER --- return actual version number as determined 
by the server.
     Only generated if the status is 204 or 304.
 
@@ -238,23 +228,25 @@ public key using the Crockford base32-encoding.
 
   *Anastasis-Policy-Signature*: Base-32 encoded EdDSA signature over hash of 
body with $ACCOUNT_PRIV, affirming desire to upload an encrypted recovery 
document.
 
+  *Payment-Identifier*: Base-32 encoded 32-byte payment identifier that was 
included in a previous payment (see 402 status code). Used to allow the server 
to check that the client paid for the upload (to protect the server against DoS 
attacks) and that the client knows a real secret of financial value (as the 
kdf_id might be known to an attacker). If this header is missing (or the 
associated payment has exceeded the upload limit), the server must return a 402 
response.  When making payme [...]
+
   **Details:**
 
   .. _EncryptedRecoveryDocument:
   .. code-block:: tsref
 
     interface EncryptedRecoveryDocument {
-      // Binary ECDHE ephemeral public key used to encrypt the gzip compressed 
JSON-encoded `RecoveryDocument`_.
-      ephemeral_pub: EcdhePublicKey;
+      // Nonce used to compute the (iv,key) pair for encryption of the
+      // encrypted_compressed_recovery_document.
+      nonce: byte[32];
 
       // Authentication tag
-      aes_gcm_tag: byte[32?];
+      aes_gcm_tag: byte[16];
 
       // Variable-size encrypted recovery document. After decryption,
       // this contains a gzip compressed JSON-encoded `RecoveryDocument`_.
       // The salt of the HKDF for this encryption must include the
       // string "EDR".
-      // FIXME: does it help including the server_salt here as well?
       encrypted_compressed_recovery_document: byte[]
 
     }
@@ -382,8 +374,8 @@ argument and signature may be optional.
       // answer to the security question)
       encrypted_key_share: byte[];
 
-      // ECDHE public key used to encrypt the encrypted_key_share
-      key_share_ephemeral_pub: EddsaPublicKey;
+      // Nonce used to generate the (iv,key) from kdf_id to AES-GCM encrypt 
the truth.
+      nonce: byte[32];
 
       // Authentication tag over the encrypted_key_share
       key_share_aes_gcm_tag: byte[32];
@@ -436,8 +428,8 @@ argument and signature may be optional.
   .. code-block:: tsref
 
     interface EncryptedKeyShare {
-      // ECDHE public key used to encrypt the gzip compressed JSON-encoded 
`KeyShare`_.
-      ephemeral_pub: EddsaPublicKey;
+      // Nonce used to compute the decryption (iv,key) pair.
+      nonce: byte[32];
 
       // Authentication tag
       aes_gcm_tag: byte[32];
@@ -480,4 +472,4 @@ argument and signature may be optional.
       // mime type of truth, i.e. text/ascii, image/jpeg, etc.
       truth_mime: string;
 
-    }
\ No newline at end of file
+    }
diff --git a/src/api/crypto-anastasis.rst b/src/api/crypto-anastasis.rst
index c9d65fd..b5df6ec 100644
--- a/src/api/crypto-anastasis.rst
+++ b/src/api/crypto-anastasis.rst
@@ -39,20 +39,15 @@ depend on the cultural context, in this document we will 
simply refer to this
 information as the **user_identifier**.
 
 This user_identifier will be first hashed with SCrypt, to provide a **kdf_id**
-which will be used to derive other keys later. The Hash must also include the 
respective **server_salt**. This also ensures that the **kdf_id** is different 
on each server. The use of SCrypt and the respective server_salt is intended
+which will be used to derive other keys later. The Hash must also include the
+respective **server_salt**. This also ensures that the **kdf_id** is different
+on each server. The use of SCrypt and the respective server_salt is intended
 to make it difficult to brute-force **kdf_id** values and help protect user's
-privacy. Also this ensures that the kdf_ids on every server differs. However, 
we do not assume that the **user_identifier** or the
-**kdf_id** cannot be determined by an adversary performing a targeted attack,
-as a user's **user_identifier** is likely to always be known to state actors
-and may likely also be available to other actors.
-
-FIXME?: What do we do if a user backs up their data using 3 different
-Anastasis operators with 3 different salts? We must check that the
-kdf_id can differ between servers, and maybe then clarify that it is
-kdf_id^S (^S = per server), instead of one value for all servers!
-NOTE that api-anastasis in the introduction already explains that the
-server_salt should NOT be used to derive the **kdf_id**. So this is
-likely wrong.?
+privacy. Also this ensures that the kdf_ids on every server differs. However,
+we do not assume that the **user_identifier** or the **kdf_id** cannot be
+determined by an adversary performing a targeted attack, as a user's
+**user_identifier** is likely to always be known to state actors and may
+likely also be available to other actors.
 
 
 .. code-block::
@@ -79,11 +74,13 @@ existing version).
 For the generation of the private key we use the kdf_id as the entropy source,
 hash it to derive a base secret which will then be processed to fit the
 requirements for EdDSA private keys.  From the private key we can then
-generate the corresponding public key.
+generate the corresponding public key.  Here, "ver" is used as a salt for the
+HKDF to ensure that the result differs from other cases where we hash
+kdf_id.
 
 .. code-block::
 
-    ver_secret:= HKDF(kdf_id, server_salt, keysize)
+    ver_secret:= HKDF(kdf_id, "ver", keysize)
     eddsa_priv := eddsa_d_to_a(ver_secret)
     eddsa_pub := get_EdDSA_Pub(eddsa_priv)
 
@@ -96,7 +93,12 @@ generate the corresponding public key.
 
 **ver_secret**: Derived key from the kdf_id, serves as intermediate step for 
the generation of the private key
 
-**eddsa_d_to_a()**: Function which converts the ver_key to a valid EdDSA 
private key.
+**eddsa_d_to_a()**: Function which converts the ver_key to a valid EdDSA 
private key. Specifically, assuming the value eddsa_priv is in a 32-byte array 
"digest", the function clears and sets certain bits as follows:
+
+.. code-block::
+
+   digest[0] = (digest[0] & 0x7f) | 0x40;
+   digest[31] &= 0xf8;
 
 **eddsa_priv**: The generated EdDSA private key.
 
@@ -109,41 +111,28 @@ generate the corresponding public key.
 For symmetric encryption of data we use AES256-GCM. For this we need a
 symmetric key and an initialization vector (IV).  To ensure that the
 symmetric key changes for each encryption operation, we compute the
-key material using Diffie-Hellman (DH), combining a long-term ECDH
-key with an ephemeral (single-use) ECDHE key.
-
-The long-term ECDH private key is again derived from the user's kdf_id.  The
-ephemeral ECDHE key is chosen at random before every encryption.
+key material using an HKDF over a nonce and the kdf_id.
 
 .. code-block::
 
-    enc_secret:= HKDF(kdf_id, salt_enc, keysize)
-    ecdh_priv := ecdhe_d_to_a(enc_secret)
-    ecdh_pub := get_ecdhe_pub(ecdh_priv)
-    ecdhe_priv := ecdhe_create(PRNG)
-    ecdhe_pub := get_ecdhe_pub(ecdhe_priv)
-    dh_secret := ecdhe(ecdhe_priv, ecdh_pub) = ecdhe(ecdh_pub, ecdhe_priv)
-    iv:= Hash(dh_secret)
-    enc_key:= HKDF(sym_key, salt_enc, keysize)
+    (iv,key) := HKDF(kdf_id, nonce, keysize + ivsize)
 
 **HKDF()**: The HKDF-function uses to phases: First we use HMAC-SHA512 for the 
extraction phase, then HMAC-SHA256 is used for expansion phase.
 
 **kdf_id**: Hashed user_identifier
 
-**key_size**: Size of the output, here 32Byte
+**keysize**: Size of the AES symmetric key, here 32 bytes
 
-**enc_secret**: Derived key material from the kdf_id, serves as intermediate 
step for the generation of the long-term private key.
+**ivsize**: Size of the AES GCM IV, here 12 bytes
 
-**ecdhe_d_to_a()**: Function which converts the enc_secret to a valid ECDH(E) 
private key.
+**prekey**: Original key material.
 
-**dh_secret**: Intermediate step for the generation of the symmetric key.
+**nonce**: 32-byte nonce, must never match "ver" (which it cannot as the 
length is different).
 
-**enc_key**: Symmetric key which is later used to encrypt the documents with 
AES256-GCM.
+**key**: Symmetric key which is later used to encrypt the documents with 
AES256-GCM.
  
 **iv**: IV which will be used for AES-GCM
 
-**Hash** SHA512 Hash with an output of 64Byte.
-
 ----------------------------
 2. Key Usage
 ----------------------------
@@ -154,10 +143,10 @@ the key_share of the user.
 2.1 Encryption
 ^^^^^^^^^^^^^^
 
-Before every encryption an ephemeral ECDHE public key is generated.
+Before every encryption a 32-byte nonce is generated.
 From this the symmetric key is computed as described above.
 We use AES256-GCM for the encryption of the recovery_document and
-key_share.   
+key_share. 
 
 FIXME: This is underspecified. ( To be adjusted after Monday(Nonce))
 
diff --git a/src/include/anastasis_database_plugin.h 
b/src/include/anastasis_database_plugin.h
index ddcc17c..082db5c 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -25,6 +25,22 @@
 #include <gnunet/gnunet_db_lib.h>
 #include <jansson.h>
 
+
+/**
+ * An EdDSA public key that is used to identify a user's account.
+ */
+struct ANASTASIS_AccountPubP {
+  struct GNUNET_EddsaPublicKey pub;
+};
+
+/**
+ * Random identifier used to later charge a payment.
+ */
+struct ANASTASIS_PaymentIdentifierP {
+  uint32_t id[8];
+};
+
+
 /**
  * Handle to interact with the database.
  */
@@ -73,46 +89,107 @@ struct AnastasisDatabasePlugin
   (*initialize) (void *cls);
 
   /**
-   * Roll back the current transaction of a database connection.
+   * Function called to perform "garbage collection" on the
+   * database, expiring records we no longer require.  Deletes
+   * all user records that are not paid up (and by cascade deletes
+   * the associated recovery documents). Also deletes expired
+   * truth and financial records older than @a fin_expire.
    *
-   * @param cls the plugin-specific state
-   * @return #GNUNET_OK on success
+   * @param cls closure
+   * @param fin_expire financial records older than the given 
+   *        time stamp should be garbage collected (usual
+   *        values might be something like 6-10 years in the past)
+   * @return transaction status
    */
-  void
-  (*rollback) (void *cls);
+  enum GNUNET_DB_QueryStatus
+  (*gc) (void *cls,
+        struct GNUNET_TIME_Absolute fin_expire);
 
   /**
-   * Start a transaction.
+   * Record user payment.
    *
-   * @param cls the plugin-specific state
-   * @param name unique name identifying the transaction (for debugging),
-   *             must point to a constant
-   * @return #GNUNET_OK on success
+   * @param cls closure
+   * @param amount how much was paid
+   * @param account_pub public key of the user's account
+   * @param num_uploads how many uploads does @a amount pay for
+   * @param lifetime_inc for how long does @a amount pay for account 
maintenance
+   * @param payment_identifier identifier for the payment, used to later 
charge on uploads
+   * @return transaction status
    */
-  int
-  (*start) (void *cls,
-            const char *name);
+  enum GNUNET_DB_QueryStatus
+  (*record_payment) (void *cls,
+                    const struct TALER_Amount *amount,
+                    const struct ANASTASIS_AccountPubP *account_pub,
+                    unsigned int num_uploads,
+                    struct GNUNET_TIME_Relative lifetime_inc,
+                    const struct ANASTASIS_PaymentIdentifierP 
*payment_identifier);
 
+  /**
+   * Record user payment.
+   *
+   * @param cls closure
+   * @param account_pub public key of the user's account
+   * @param encrypted_policy_document_size FIXME
+   * @param encrypted_policy_document FIXME
+   * @param payment_identifier identifier for the payment, used to later 
charge on uploads
+   * @param version[OUT] set to the version assigned to the document by the 
database
+   * @return transaction status, 0 if upload could not be finished because @a 
payment_identifier
+   *         did not have enough upload left; HARD error if @a 
payment_identifier is unknown, ...
+   */
+  enum GNUNET_DB_QueryStatus
+  (*upload_policy) (void *cls,
+                   const struct ANASTASIS_AccountPubP *account_pub,
+                   size_t encrypted_policy_document_size,
+                   const void *encrypted_policy_document,
+                   const struct ANASTASIS_PaymentIdentifierP 
*payment_identifier,
+                   uint32_t *version);
 
   /**
-   * Do a pre-flight check that we are not in an uncommitted transaction.
-   * If we are, try to commit the previous transaction and output a warning.
-   * Does not return anything, as we will continue regardless of the outcome.
+   * Fetch policy for user.
    *
-   * @param cls the plugin-specific state
+   * @param cls closure
+   * @param account_pub public key of the user's account
+   * @param version FIXME
+   * @param encrypted_policy_document_size[OUT] FIXME
+   * @param encrypted_policy_document[OUT] FIXME
+   * @param payment_identifier identifier for the payment, used to later 
charge on uploads
+   * @return transaction status
    */
-  void
-  (*preflight) (void *cls);
+  enum GNUNET_DB_QueryStatus
+  (*get_policy) (void *cls,
+                const struct ANASTASIS_AccountPubP *account_pub,
+                uint32_t version,
+                size_t *encrypted_policy_document_size,
+                void **encrypted_policy_document);
 
 
   /**
-   * Commit the current transaction of a database connection.
+   * Fetch latest policy for user.
    *
-   * @param cls the plugin-specific state
-   * @return transaction status code
+   * @param cls closure
+   * @param account_pub public key of the user's account
+   * @param version[OUT] set to the version number of the policy being returned
+   * @param encrypted_policy_document_size[OUT] FIXME
+   * @param encrypted_policy_document[OUT] FIXME
+   * @param payment_identifier identifier for the payment, used to later 
charge on uploads
+   * @return transaction status
    */
   enum GNUNET_DB_QueryStatus
-  (*commit) (void *cls);
+  (*get_latest_policy) (void *cls,
+                       const struct ANASTASIS_AccountPubP *account_pub,
+                       size_t *encrypted_policy_document_size,
+                       void **encrypted_policy_document,
+                       uint32_t *version);
+
+  
+  
+  /**
+   *
+   * @param cls the plugin-specific state
+   */
+  void
+  (*preflight) (void *cls);
+
 
 };
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]