diff options
-rw-r--r-- | src/include/anastasis_crypto_lib.h | 60 | ||||
-rw-r--r-- | src/lib/anastasis_backup.c | 27 | ||||
-rw-r--r-- | src/lib/anastasis_recovery.c | 42 | ||||
-rw-r--r-- | src/util/anastasis_crypto.c | 148 | ||||
-rw-r--r-- | src/util/test_anastasis_crypto.c | 25 |
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; } |