summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/anastasis_crypto_lib.h60
-rw-r--r--src/lib/anastasis_backup.c27
-rw-r--r--src/lib/anastasis_recovery.c42
-rw-r--r--src/util/anastasis_crypto.c148
-rw-r--r--src/util/test_anastasis_crypto.c25
5 files changed, 190 insertions, 112 deletions
diff --git a/src/include/anastasis_crypto_lib.h b/src/include/anastasis_crypto_lib.h
index 6377baf..0075be7 100644
--- a/src/include/anastasis_crypto_lib.h
+++ b/src/include/anastasis_crypto_lib.h
@@ -133,15 +133,6 @@ struct ANASTASIS_CRYPTO_PolicyKeyP
/**
- * Specifies an encrypted master key, the key is used to encrypt the core secret from the user
- */
-struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
-{
- struct GNUNET_HashCode key GNUNET_PACKED;
-};
-
-
-/**
* Specifies a Nonce used for the AES encryption, here defined as 32Byte large.
*/
struct ANASTASIS_CRYPTO_NonceP
@@ -271,6 +262,33 @@ struct ANASTASIS_AccountSignatureP
GNUNET_NETWORK_STRUCT_END
+/**
+ * Result of encrypting the core secret.
+ */
+struct ANASTASIS_CoreSecretEncryptionResult
+{
+ /**
+ * Encrypted core secret.
+ */
+ void *enc_core_secret;
+
+ /**
+ * Size of the encrypted core secret.
+ */
+ size_t enc_core_secret_size;
+
+ /**
+ * Array of encrypted master keys. Each key is encrypted
+ * to a different policy key.
+ */
+ void **enc_master_keys;
+
+ /**
+ * Sizes of the encrypted master keys.
+ */
+ size_t *enc_master_key_sizes;
+};
+
/**
* Hash a numerical answer to compute the hash value to be submitted
@@ -498,18 +516,24 @@ ANASTASIS_CRYPTO_policy_key_derive (
* @param policy_keys_length defines the amount of policy keys and also the amount of encrypted master keys
* @param core_secret the user provided core secret which is secured by anastasis
* @param core_secret_size the size of the core secret
- * @param[out] enc_core_secret the core secret is encrypted with the generated master key
- * @param[out] encrypted_master_keys array of encrypted master keys which will be safed inside the policies one encrypted
- * master key is created for each policy key
+ * @returns result of the encryption, must be freed with #ANASTASIS_CRYPTO_destroy_encrypted_core_secret
*/
-void
+struct ANASTASIS_CoreSecretEncryptionResult *
ANASTASIS_CRYPTO_core_secret_encrypt (
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
unsigned int policy_keys_length,
const void *core_secret,
- size_t core_secret_size,
- void **enc_core_secret,
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys);
+ size_t core_secret_size);
+
+
+/**
+ * Destroy a core secret encryption result.
+ *
+ * @param cser the result to destroy
+ */
+void
+ANASTASIS_CRYPTO_destroy_encrypted_core_secret (
+ struct ANASTASIS_CoreSecretEncryptionResult *cser);
/**
@@ -517,6 +541,7 @@ ANASTASIS_CRYPTO_core_secret_encrypt (
* Afterwards the core secret is encrypted with the master key. The core secret is returned.
*
* @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key
+ * @param encrypted_master_key_size size of the encrypted master key
* @param policy_key built policy key which will decrypt the master key
* @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key
* @param encrypted_core_secret_size size of the encrypted core secret
@@ -525,7 +550,8 @@ ANASTASIS_CRYPTO_core_secret_encrypt (
*/
void
ANASTASIS_CRYPTO_core_secret_recover (
- const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key,
+ const void *encrypted_master_key,
+ size_t encrypted_master_key_size,
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key,
const void *encrypted_core_secret,
size_t encrypted_core_secret_size,
diff --git a/src/lib/anastasis_backup.c b/src/lib/anastasis_backup.c
index a1f162a..b9981f0 100644
--- a/src/lib/anastasis_backup.c
+++ b/src/lib/anastasis_backup.c
@@ -729,9 +729,7 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
size_t core_secret_size)
{
struct ANASTASIS_SecretShare *ss;
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
- encrypted_master_keys[GNUNET_NZL (policies_len)];
- void *encrypted_core_secret;
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
json_t *dec_policies;
json_t *esc_methods;
size_t recovery_document_size;
@@ -755,12 +753,10 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
for (unsigned int i = 0; i < policies_len; i++)
policy_keys[i] = policies[i]->policy_key;
- ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
- policies_len,
- core_secret,
- core_secret_size,
- &encrypted_core_secret,
- encrypted_master_keys);
+ cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
+ policies_len,
+ core_secret,
+ core_secret_size);
}
dec_policies = json_array ();
GNUNET_assert (NULL != dec_policies);
@@ -780,8 +776,10 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
json_array_append_new (
dec_policies,
GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_key",
- &encrypted_master_keys[k]),
+ GNUNET_JSON_pack_data_varsize ("master_key",
+ cser->enc_master_keys[k],
+ cser->enc_master_key_sizes
+ [k]),
GNUNET_JSON_pack_array_steal ("uuids",
uuids),
GNUNET_JSON_pack_data_auto ("salt",
@@ -855,10 +853,11 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
GNUNET_JSON_pack_array_steal ("escrow_methods",
esc_methods),
GNUNET_JSON_pack_data_varsize ("encrypted_core_secret",
- encrypted_core_secret,
- core_secret_size));
+ cser->enc_core_secret,
+ cser->enc_core_secret_size));
GNUNET_assert (NULL != recovery_document);
- GNUNET_free (encrypted_core_secret);
+ ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser);
+ cser = NULL;
rd_str = json_dumps (recovery_document,
JSON_COMPACT | JSON_SORT_KEYS);
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index ac10418..aca9d29 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -118,9 +118,14 @@ struct DecryptionPolicy
struct ANASTASIS_DecryptionPolicy pub_details;
/**
- * Encrypted masterkey (encrypted with the policy key).
+ * Encrypted master key (encrypted with the policy key).
*/
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP emk;
+ void *emk;
+
+ /**
+ * Size of the encrypted master key.
+ */
+ size_t emk_size;
/**
* Salt used to decrypt master key.
@@ -439,7 +444,10 @@ keyshare_lookup_cb (void *cls,
rdps->pub_details.challenges_length,
&rdps->salt,
&policy_key);
- ANASTASIS_CRYPTO_core_secret_recover (&rdps->emk,
+ GNUNET_assert (NULL != rdps->emk);
+ GNUNET_assert (rdps->emk_size > 0);
+ ANASTASIS_CRYPTO_core_secret_recover (rdps->emk,
+ rdps->emk_size,
&policy_key,
recovery->enc_core_secret,
recovery->enc_core_secret_size,
@@ -822,12 +830,14 @@ policy_lookup_cb (void *cls,
for (unsigned int j = 0; j < r->ri.dps_len; j++)
{
struct DecryptionPolicy *dp = &r->dps[j];
+
json_t *uuids = NULL;
json_t *uuid;
size_t n_index;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("master_key",
- &dp->emk),
+ GNUNET_JSON_spec_varsize ("master_key",
+ &dp->emk,
+ &dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("salt",
&dp->salt),
GNUNET_JSON_spec_json ("uuids",
@@ -854,6 +864,9 @@ policy_lookup_cb (void *cls,
return;
}
+ GNUNET_assert (NULL != dp->emk);
+ GNUNET_assert (dp->emk_size > 0);
+
dp->pub_details.challenges_length = json_array_size (uuids);
dp->pub_details.challenges
= GNUNET_new_array (dp->pub_details.challenges_length,
@@ -997,9 +1010,11 @@ ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r)
json_array_append_new (c_arr,
cs));
}
+ GNUNET_assert (NULL != dp->emk);
dps = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("emk",
- &dp->emk),
+ GNUNET_JSON_pack_data_varsize ("emk",
+ dp->emk,
+ dp->emk_size),
GNUNET_JSON_pack_data_auto ("salt",
&dp->salt),
GNUNET_JSON_pack_array_steal ("challenges",
@@ -1187,8 +1202,9 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
struct DecryptionPolicy *dp = &r->dps[n_index];
json_t *challenges;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("emk",
- &dp->emk),
+ GNUNET_JSON_spec_varsize ("emk",
+ &dp->emk,
+ &dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("salt",
&dp->salt),
GNUNET_JSON_spec_json ("challenges",
@@ -1213,6 +1229,8 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
JSON_INDENT (2));
return GNUNET_SYSERR;
}
+ GNUNET_assert (NULL != dp->emk);
+ GNUNET_assert (dp->emk_size > 0);
if (! json_is_array (challenges))
{
GNUNET_break_op (0);
@@ -1263,7 +1281,8 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
}
}
}
- GNUNET_JSON_parse_free (spec);
+ /* We don't free the spec, since we're still using dp->ems. */
+ json_decref (challenges);
}
return GNUNET_OK;
}
@@ -1428,7 +1447,10 @@ ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r)
}
GNUNET_free (r->solved_challenges);
for (unsigned int j = 0; j < r->ri.dps_len; j++)
+ {
GNUNET_free (r->dps[j].pub_details.challenges);
+ GNUNET_free (r->dps[j].emk);
+ }
GNUNET_free (r->ri.dps);
for (unsigned int i = 0; i < r->ri.cs_len; i++)
{
diff --git a/src/util/anastasis_crypto.c b/src/util/anastasis_crypto.c
index bed0a94..067ac92 100644
--- a/src/util/anastasis_crypto.c
+++ b/src/util/anastasis_crypto.c
@@ -239,6 +239,7 @@ anastasis_decrypt (const void *key,
if (*res_size >= data_size)
{
GNUNET_break (0);
+ *res = NULL;
return;
}
*res = GNUNET_malloc (*res_size);
@@ -530,93 +531,110 @@ ANASTASIS_CRYPTO_policy_key_derive (
}
-void
+struct ANASTASIS_CoreSecretEncryptionResult *
ANASTASIS_CRYPTO_core_secret_encrypt (
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
unsigned int policy_keys_length,
const void *core_secret,
- size_t core_secret_size,
- void **enc_core_secret,
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys)
+ size_t core_secret_size)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
struct GNUNET_HashCode master_key;
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
+ struct ANASTASIS_CRYPTO_NonceP nonce;
+
+ cser = GNUNET_new (struct ANASTASIS_CoreSecretEncryptionResult);
- *enc_core_secret = GNUNET_malloc (core_secret_size);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
&master_key,
sizeof (struct GNUNET_HashCode));
- GNUNET_CRYPTO_hash_to_aes_key (&master_key,
- &sk,
- &iv);
- GNUNET_assert (GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_encrypt (core_secret,
- core_secret_size,
- &sk,
- &iv,
- *enc_core_secret));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &nonce,
+ sizeof (struct ANASTASIS_CRYPTO_NonceP));
+
+ anastasis_encrypt (&nonce,
+ &master_key,
+ sizeof (struct GNUNET_HashCode),
+ core_secret,
+ core_secret_size,
+ "cse",
+ &cser->enc_core_secret,
+ &cser->enc_core_secret_size);
+
+ /* Allocate result arrays with NULL-termination so we don't
+ need to store the length to free */
+ cser->enc_master_key_sizes = GNUNET_new_array (policy_keys_length + 1,
+ size_t);
+ cser->enc_master_keys = GNUNET_new_array (policy_keys_length + 1,
+ void *);
+
for (unsigned int i = 0; i < policy_keys_length; i++)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey i_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector i_iv;
- struct GNUNET_HashCode key = policy_keys[i].key;
-
- GNUNET_CRYPTO_hash_to_aes_key (&key,
- &i_sk,
- &i_iv);
- GNUNET_assert (
- GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_encrypt (&master_key,
- sizeof (struct GNUNET_HashCode),
- &i_sk,
- &i_iv,
- &encrypted_master_keys[i]));
+ struct ANASTASIS_CRYPTO_NonceP nonce_i;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &nonce_i,
+ sizeof (struct ANASTASIS_CRYPTO_NonceP));
+
+ anastasis_encrypt (&nonce_i,
+ &policy_keys[i].key,
+ sizeof (struct GNUNET_HashCode),
+ &master_key,
+ sizeof (struct GNUNET_HashCode),
+ "emk",
+ &cser->enc_master_keys[i],
+ &cser->enc_master_key_sizes[i]);
}
+ return cser;
}
+/**
+ * Decrypts the core secret with the master key. First the master key is decrypted with the provided policy key.
+ * Afterwards the core secret is encrypted with the master key. The core secret is returned.
+ *
+ * @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key
+ * @param encrypted_master_key_size size of the encrypted master key
+ * @param policy_key built policy key which will decrypt the master key
+ * @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key
+ * @param encrypted_core_secret_size size of the encrypted core secret
+ * @param[out] core_secret decrypted core secret will be returned
+ * @param[out] core_secret_size size of core secret
+ */
void
ANASTASIS_CRYPTO_core_secret_recover (
- const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key,
+ const void *encrypted_master_key,
+ size_t encrypted_master_key_size,
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key,
const void *encrypted_core_secret,
size_t encrypted_core_secret_size,
void **core_secret,
size_t *core_secret_size)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey mk_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector mk_iv;
- struct GNUNET_CRYPTO_SymmetricSessionKey core_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector core_iv;
- struct GNUNET_HashCode master_key;
- struct GNUNET_HashCode key = policy_key->key;
+ void *master_key;
+ size_t master_key_size;
*core_secret = GNUNET_malloc (encrypted_core_secret_size);
- GNUNET_CRYPTO_hash_to_aes_key (&key,
- &mk_sk,
- &mk_iv);
- GNUNET_assert (
- GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_decrypt (
- encrypted_master_key,
- sizeof (struct ANASTASIS_CRYPTO_EncryptedMasterKeyP),
- &mk_sk,
- &mk_iv,
- &master_key));
- GNUNET_CRYPTO_hash_to_aes_key (&master_key,
- &core_sk,
- &core_iv);
+ anastasis_decrypt (&policy_key->key,
+ sizeof (struct GNUNET_HashCode),
+ encrypted_master_key,
+ encrypted_master_key_size,
+ "emk",
+ &master_key,
+ &master_key_size);
+ GNUNET_break (NULL != master_key);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"At %s:%d encrypted core secret is %s-%llu b\n", __FILE__,
__LINE__,
TALER_b2s (encrypted_core_secret, encrypted_core_secret_size),
(unsigned long long) encrypted_core_secret_size);
- *core_secret_size = GNUNET_CRYPTO_symmetric_decrypt (encrypted_core_secret,
- encrypted_core_secret_size,
- &core_sk,
- &core_iv,
- *core_secret);
+ anastasis_decrypt (master_key,
+ master_key_size,
+ encrypted_core_secret,
+ encrypted_core_secret_size,
+ "cse",
+ core_secret,
+ core_secret_size);
+ GNUNET_break (NULL != *core_secret);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"At %s:%d decrypted core secret is %s-%llu b\n", __FILE__,
__LINE__,
@@ -626,4 +644,22 @@ ANASTASIS_CRYPTO_core_secret_recover (
}
+/**
+ * Destroy a core secret encryption result.
+ *
+ * @param cser the result to destroy
+ */
+void
+ANASTASIS_CRYPTO_destroy_encrypted_core_secret (
+ struct ANASTASIS_CoreSecretEncryptionResult *cser)
+{
+ for (unsigned int i = 0; NULL != cser->enc_master_keys[i]; i++)
+ GNUNET_free (cser->enc_master_keys[i]);
+ GNUNET_free (cser->enc_master_keys);
+ GNUNET_free (cser->enc_master_key_sizes);
+ GNUNET_free (cser->enc_core_secret);
+ GNUNET_free (cser);
+}
+
+
/* end of anastasis_crypto.c */
diff --git a/src/util/test_anastasis_crypto.c b/src/util/test_anastasis_crypto.c
index b435bea..428aebf 100644
--- a/src/util/test_anastasis_crypto.c
+++ b/src/util/test_anastasis_crypto.c
@@ -216,11 +216,9 @@ test_core_secret (void)
{
const char *test = "TEST_CORE_SECRET";
const char *test_wrong = "TEST_CORE_WRONG";
- void *enc_core_secret;
unsigned int policy_keys_length = 5;
struct ANASTASIS_CRYPTO_MasterSaltP salt;
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
- encrypted_master_keys[policy_keys_length];
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&salt,
@@ -258,14 +256,10 @@ test_core_secret (void)
TALER_b2s (test, strlen (test)));
// test encryption of core_secret
- ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
- policy_keys_length,
- test,
- strlen (test),
- &enc_core_secret,
- (struct
- ANASTASIS_CRYPTO_EncryptedMasterKeyP *)
- &encrypted_master_keys);
+ cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
+ policy_keys_length,
+ test,
+ strlen (test));
// test recover of core secret
for (unsigned int k = 0; k < policy_keys_length; k++)
@@ -273,10 +267,11 @@ test_core_secret (void)
void *dec_core_secret;
size_t core_secret_size;
- ANASTASIS_CRYPTO_core_secret_recover (&encrypted_master_keys[k],
+ ANASTASIS_CRYPTO_core_secret_recover (cser->enc_master_keys[k],
+ cser->enc_master_key_sizes[k],
&policy_keys[k],
- enc_core_secret,
- strlen (test),
+ cser->enc_core_secret,
+ cser->enc_core_secret_size,
&dec_core_secret,
&core_secret_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -291,7 +286,7 @@ test_core_secret (void)
test)));
GNUNET_free (dec_core_secret);
}
- GNUNET_free (enc_core_secret);
+ ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser);
return 0;
}