diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-10-08 12:19:09 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-10-08 12:19:09 +0200 |
commit | f85d5432c4bc4f0a922822265976eb2823eedada (patch) | |
tree | 14fa56123fc9823f33a019e7204890867d410a41 | |
parent | aa0e7b1575273ad22f7e5f51d0c8207f5ecd4f9c (diff) | |
download | docs-f85d5432c4bc4f0a922822265976eb2823eedada.tar.gz docs-f85d5432c4bc4f0a922822265976eb2823eedada.tar.bz2 docs-f85d5432c4bc4f0a922822265976eb2823eedada.zip |
integrate anastasis specs into one document
-rw-r--r-- | anastasis.rst (renamed from api-anastasis.rst) | 189 | ||||
-rw-r--r-- | crypto-anastasis.rst | 176 | ||||
-rw-r--r-- | index.rst | 3 |
3 files changed, 175 insertions, 193 deletions
diff --git a/api-anastasis.rst b/anastasis.rst index 99dbb7e9..addbce36 100644 --- a/api-anastasis.rst +++ b/anastasis.rst @@ -17,9 +17,9 @@ @author Dominik Meister @author Dennis Neufeld -============================== -The Anastasis RESTful JSON API -============================== +========= +Anastasis +========= **Anastasis** is a service that allows the user to securely deposit a master secret with an open set of escrow providers and recover it if it is lost. To @@ -67,11 +67,170 @@ authorize themself. The **truth** API allows the user to provide the data required for the respective authorization method. +--------------- +Key derivations +--------------- + +EdDSA and ECDHE public keys are always points on Curve25519 and represented +using the standard 256 bit Ed25519 compact format. The binary representation +is converted to Crockford Base32 when transmitted inside JSON or as part of +URLs. + +To start, a user provides their private, unique and unforgettable +**identifier** as a seed to identify their account. For example, this could +be a social security number together with their full name. Specifics may +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 +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. + + +.. code-block:: tsref + + kdf_id := SCrypt( user_identifier, server_salt, keysize ) + +**user_identifier**: The secret defined from the user beforehand. + +**server_salt**: The salt from the Server + +**keysize**: The desired output size of the KDF, here 32 bytes. + + +Verification +^^^^^^^^^^^^ + +For users to authorize **policy** operations we need an EdDSA key pair. As we +cannot assure that the corresponding private key is truly secret, such policy +operations must never be destructive: Should an adversary learn the private +key, they could access (and with the kdf_id decrypt) the user's policy (but +not the core secret), or upload a new version of the policy (but not delete an +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. 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:: tsref + + ver_secret:= HKDF(kdf_id, "ver", keysize) + eddsa_priv := eddsa_d_to_a(ver_secret) + eddsa_pub := get_EdDSA_Pub(eddsa_priv) + + +**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 32 bytes. + +**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. Specifically, assuming the value eddsa_priv is in a 32-byte array "digest", the function clears and sets certain bits as follows: + +.. code-block:: tsref + + digest[0] = (digest[0] & 0x7f) | 0x40; + digest[31] &= 0xf8; + +**eddsa_priv**: The generated EdDSA private key. + +**eddsa_pub**: The generated EdDSA public key. + + +Encryption +^^^^^^^^^^ + +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 an HKDF over a nonce and the kdf_id. + +.. code-block:: tsref + + (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 + +**keysize**: Size of the AES symmetric key, here 32 bytes + +**ivsize**: Size of the AES GCM IV, here 12 bytes + +**prekey**: Original key material. + +**nonce**: 32-byte nonce, must never match "ver" (which it cannot as the length is different). + +**key**: Symmetric key which is later used to encrypt the documents with AES256-GCM. + +**iv**: IV which will be used for AES-GCM + + +--------- +Key Usage +--------- + +The keys we have generated, are now used to encrypt the recovery_document and +the key_share of the user. + + +Encryption +^^^^^^^^^^ + +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. + +.. code-block:: tsref + + (encrypted_recovery_document, aes_gcm_tag) = AES256_GCM(recovery_document, key, iv) + (encrypted_key_share, aes_gcm_tag) = AES256_GCM(key_share, key, iv) + +**encrypted_recovery_document**: The encrypted RecoveryDocument (recovery_document) which contains the policies. + +**encrypted_key_share**: The encrypted KeyShare (key_share). + +Signatures +^^^^^^^^^^ + +The EdDSA keys are used to sign the data sent from the client to the +server. Everything the client sends to server is signed. The following algorithm is equivalent for **Anastasis-Policy-Signature**. + +.. code-block:: tsref + + (anastasis-account-signature) = eddsa_sign(h_body, eddsa_priv) + ver_res = eddsa_verifiy(h_body, anastasis-account-signature, eddsa_pub) + +**anastasis-account-signature**: Signature over the hash of body. + +**h_body**: The hashed body. + +**ver_res**: A boolean value. True: Verification passed, False: Verification failed. + + + +------------- +Anastasis API +------------- + .. _salt: ------------ + Obtain salt ------------ +^^^^^^^^^^^ .. http:get:: /salt @@ -97,9 +256,9 @@ Obtain salt .. _terms: --------------------------- + Receiving Terms of Service --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ .. http:get:: /terms @@ -139,9 +298,9 @@ Receiving Terms of Service .. _escrow: -------------- + Manage policy -------------- +^^^^^^^^^^^^^ This API is used by the Anastasis client to deposit or request encrypted recovery documents with the escrow provider. Generally, a client will deposit @@ -195,7 +354,7 @@ public key using the Crockford base32-encoding. *If-modified-since*: If the client has previously received an Etag from the server, he has to send it with this request (to avoid unnecessary downloads). - *If-None-Match*: If this is not the very first request of the client, this contains the Etag-Value which the client has reveived before from the server. + *If-None-Match*: If this is not the very first request of the client, this contains the Etag-Value which the client has reveived before from the server. The client must send this header with every request (except for the very first request). *Anastasis-Account-Signature*: The client must provide Base-32 encoded EdDSA signature over hash of body with $ACCOUNT_PRIV, affirming desire to download the requested encrypted recovery document. @@ -226,7 +385,7 @@ 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. - + *Anastasis-Version*: $NUMBER --- The server must return the actual version number it determined. Only generated if the status is 204 or 304. @@ -326,9 +485,9 @@ public key using the Crockford base32-encoding. .. _truth: --------------- + Managing truth --------------- +^^^^^^^^^^^^^^ This API is used by the Anastasis client to deposit or request **truth** with the escrow provider. As with the policy, the user may be identified and @@ -385,7 +544,7 @@ argument and signature may be optional. // Authentication tag over the encrypted_key_share key_share_aes_gcm_tag: byte[32]; - + // ground truth, i.e. H(challenge answer), // phone number, e-mail address, picture, fingerprint, ... // base32 encoded @@ -450,7 +609,7 @@ argument and signature may be optional. // on the method, the HKDF may additionally include // bits from the response (i.e. some hash over the // answer to the security question) - encrypted_key_share: byte[]; + encrypted_key_share: byte[]; } diff --git a/crypto-anastasis.rst b/crypto-anastasis.rst deleted file mode 100644 index 9b154a92..00000000 --- a/crypto-anastasis.rst +++ /dev/null @@ -1,176 +0,0 @@ -.. - This file is part of GNU TALER. - Copyright (C) 2019 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 2.1, 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - - @author Christian Grothoff - @author Dominik Meister - @author Dennis Neufeld - - -========================================== -Specification of Cryptography in Anastasis -========================================== -This document specifies the Crypto used in Anastasis. - ---------------- -Key derivations ---------------- - -EdDSA and ECDHE public keys are always points on Curve25519 and represented -using the standard 256 bit Ed25519 compact format. The binary representation -is converted to Crockford Base32 when transmitted inside JSON or as part of -URLs. - -To start, a user provides their private, unique and unforgettable -**identifier** as a seed to identify their account. For example, this could -be a social security number together with their full name. Specifics may -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 -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. - - -.. code-block:: tsref - - kdf_id := SCrypt( user_identifier, server_salt, keysize ) - -**user_identifier**: The secret defined from the user beforehand. - -**server_salt**: The salt from the Server - -**keysize**: The desired output size of the KDF, here 32 bytes. - - -Verification -^^^^^^^^^^^^ - -For users to authorize **policy** operations we need an EdDSA key pair. As we -cannot assure that the corresponding private key is truly secret, such policy -operations must never be destructive: Should an adversary learn the private -key, they could access (and with the kdf_id decrypt) the user's policy (but -not the core secret), or upload a new version of the policy (but not delete an -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. 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:: tsref - - ver_secret:= HKDF(kdf_id, "ver", keysize) - eddsa_priv := eddsa_d_to_a(ver_secret) - eddsa_pub := get_EdDSA_Pub(eddsa_priv) - - -**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 32 bytes. - -**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. Specifically, assuming the value eddsa_priv is in a 32-byte array "digest", the function clears and sets certain bits as follows: - -.. code-block:: tsref - - digest[0] = (digest[0] & 0x7f) | 0x40; - digest[31] &= 0xf8; - -**eddsa_priv**: The generated EdDSA private key. - -**eddsa_pub**: The generated EdDSA public key. - - -Encryption -^^^^^^^^^^ - -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 an HKDF over a nonce and the kdf_id. - -.. code-block:: tsref - - (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 - -**keysize**: Size of the AES symmetric key, here 32 bytes - -**ivsize**: Size of the AES GCM IV, here 12 bytes - -**prekey**: Original key material. - -**nonce**: 32-byte nonce, must never match "ver" (which it cannot as the length is different). - -**key**: Symmetric key which is later used to encrypt the documents with AES256-GCM. - -**iv**: IV which will be used for AES-GCM - ----------------------------- -Key Usage ----------------------------- - -The keys we have generated, are now used to encrypt the recovery_document and -the key_share of the user. - - -Encryption -^^^^^^^^^^ - -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. - -.. code-block:: tsref - - (encrypted_recovery_document, aes_gcm_tag) = AES256_GCM(recovery_document, key, iv) - (encrypted_key_share, aes_gcm_tag) = AES256_GCM(key_share, key, iv) - -**encrypted_recovery_document**: The encrypted RecoveryDocument (recovery_document) which contains the policies. - -**encrypted_key_share**: The encrypted KeyShare (key_share). - -Signatures -^^^^^^^^^^ - -The EdDSA keys are used to sign the data sent from the client to the -server. Everything the client sends to server is signed. The following algorithm is equivalent for **Anastasis-Policy-Signature**. - -.. code-block:: tsref - - (anastasis-account-signature) = eddsa_sign(h_body, eddsa_priv) - ver_res = eddsa_verifiy(h_body, anastasis-account-signature, eddsa_pub) - -**anastasis-account-signature**: Signature over the hash of body. - -**h_body**: The hashed body. - -**ver_res**: A boolean value. True: Verification passed, False: Verification failed. @@ -59,8 +59,7 @@ Documentation Overview taler-bank-manual taler-backoffice-manual onboarding - api-anastasis - crypto-anastasis + anastasis libeufin/index global-licensing manindex |