aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2018-06-15 12:26:45 -0400
committerFranklin Wei <me@fwei.tk>2018-06-15 12:26:45 -0400
commit62b6943d450944b7d461e8fc20049aa672c4e201 (patch)
treede52319f16ef6a56fb112347d545feca31f17bea
parentfba7a547b3626e5ce3980623cd111dc84b854762 (diff)
downloadcsaa-62b6943d450944b7d461e8fc20049aa672c4e201.zip
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.gz
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.bz2
csaa-62b6943d450944b7d461e8fc20049aa672c4e201.tar.xz
Working on service provider's request handling; some cleanup too
-rw-r--r--helper.c44
-rw-r--r--helper.h17
-rw-r--r--service_provider.c88
-rw-r--r--service_provider.h9
-rw-r--r--trusted_module.c6
-rw-r--r--trusted_module.h30
6 files changed, 174 insertions, 20 deletions
diff --git a/helper.c b/helper.c
index 1646c1e..2474d87 100644
--- a/helper.c
+++ b/helper.c
@@ -47,6 +47,9 @@ struct tm_cert cert_rv(const struct trusted_module *tm,
b, nonexist, hmac_nonexist);
}
+/* Fill out a user_request struct to create a file with the index
+ * given in file_node->idx with the user added with level 3 access in
+ * the ACL. */
struct user_request req_filecreate(const struct trusted_module *tm,
uint64_t user_id,
const struct iomt_node *file_node,
@@ -81,6 +84,9 @@ struct user_request req_filecreate(const struct trusted_module *tm,
return req;
}
+/* Fill out a user_request struct to modify an existing file's
+ * contents, given the previously generated FR certificate, and the
+ * ACL node giving the user's access rights. */
struct user_request req_filemodify(const struct trusted_module *tm,
const struct tm_cert *fr_cert, hash_t fr_hmac,
const struct iomt_node *file_node,
@@ -116,3 +122,41 @@ struct user_request req_filemodify(const struct trusted_module *tm,
return req;
}
+
+/* Fill out a user_request struct to modify a file's ACL. Same
+ * parameters as req_filemodify(), except the hash is the root of the
+ * new ACL. */
+struct user_request req_aclmodify(const struct trusted_module *tm,
+ const struct tm_cert *fr_cert, hash_t fr_hmac,
+ const struct iomt_node *file_node,
+ const hash_t *file_comp, const int *file_orders, size_t file_n,
+ const struct iomt_node *oldacl_node,
+ const hash_t *oldacl_comp, const int *oldacl_orders, size_t oldacl_n,
+ hash_t newacl_root)
+{
+ struct user_request req;
+ req.type = ACL_UPDATE;
+
+ req.idx = file_node->idx;
+ req.counter = hash_to_u64(file_node->val);
+
+ req.user_id = oldacl_node->idx;
+
+ req.modify.fr_cert = *fr_cert;
+ req.modify.fr_hmac = fr_hmac;
+
+ req.modify.rv_cert = cert_rv(tm,
+ oldacl_node,
+ oldacl_comp, oldacl_orders, oldacl_n,
+ &req.modify.rv_hmac,
+ 0, NULL, NULL);
+
+ hash_t next_counter = u64_to_hash(req.counter + 1);
+
+ req.modify.ru_cert = cert_ru(tm, file_node, next_counter,
+ file_comp, file_orders, file_n,
+ &req.modify.ru_hmac);
+ req.val = newacl_root;
+
+ return req;
+}
diff --git a/helper.h b/helper.h
index 1b29711..b46bf03 100644
--- a/helper.h
+++ b/helper.h
@@ -13,11 +13,17 @@ struct tm_cert cert_rv(const struct trusted_module *tm,
uint64_t b,
struct tm_cert *nonexist, hash_t *hmac_nonexist);
+/* Fill out a user_request struct to create a file with the index
+ * given in file_node->idx with the user added with level 3 access in
+ * the ACL. */
struct user_request req_filecreate(const struct trusted_module *tm,
uint64_t user_id,
const struct iomt_node *file_node,
const hash_t *file_comp, const int *file_orders, size_t file_n);
+/* Fill out a user_request struct to modify an existing file's
+ * contents, given the previously generated FR certificate, and the
+ * ACL node giving the user's access rights. */
struct user_request req_filemodify(const struct trusted_module *tm,
const struct tm_cert *fr_cert, hash_t fr_hmac,
const struct iomt_node *file_node,
@@ -25,3 +31,14 @@ struct user_request req_filemodify(const struct trusted_module *tm,
const struct iomt_node *acl_node,
const hash_t *acl_comp, const int *acl_orders, size_t acl_n,
hash_t fileval);
+
+/* Fill out a user_request struct to modify a file's ACL. Same
+ * parameters as req_filemodify(), except the hash is the root of the
+ * new ACL. */
+struct user_request req_aclmodify(const struct trusted_module *tm,
+ const struct tm_cert *fr_cert, hash_t fr_hmac,
+ const struct iomt_node *file_node,
+ const hash_t *file_comp, const int *file_orders, size_t file_n,
+ const struct iomt_node *oldacl_node,
+ const hash_t *oldacl_comp, const int *oldacl_orders, size_t oldacl_n,
+ hash_t newacl_root);
diff --git a/service_provider.c b/service_provider.c
index 8469d1a..7f87b72 100644
--- a/service_provider.c
+++ b/service_provider.c
@@ -12,12 +12,12 @@
#include "trusted_module.h"
struct file_version {
- hash_t kf; /* h(key, file_idx) */
- hash_t l; /* h(h(file contents), kf) */
- hash_t enc_key; /* XOR'd with h(kf, module secret) */
+ hash_t kf; /* HMAC(key, file_idx) */
+ hash_t l; /* HMAC(h(encrypted contents), kf) */
+ hash_t encrypted_secret; /* XOR'd with HMAC(kf, module secret) */
- struct tm_cert cert; /* VR certificate */
- hash_t cert_hmac;
+ struct tm_cert vr_cert; /* VR certificate */
+ hash_t vr_hmac;
void *contents;
size_t len;
@@ -35,7 +35,7 @@ struct file_record {
hash_t fr_hmac;
struct file_version *versions;
- int n_versions;
+ int nversions;
};
struct service_provider {
@@ -292,19 +292,39 @@ static struct file_record *lookup_record(struct service_provider *sp, int idx)
/* We do not check to ensure that there are no duplicate file indices;
* this is up to the caller */
-static void insert_record(struct service_provider *sp, struct file_record *rec)
+static void append_record(struct service_provider *sp, const struct file_record *rec)
{
sp->records = realloc(sp->records, sizeof(struct file_record) * ++sp->nrecords);
sp->records[sp->nrecords - 1] = *rec;
}
-/* this does the majority of the work that actually modifies or
- * creates a file */
+static void append_version(struct file_record *rec, const struct file_version *ver)
+{
+ rec->versions = realloc(rec->versions, sizeof(struct file_version) * ++rec->nversions);
+ rec->versions[rec->nversions - 1] = *ver;
+}
+
+/* This does the majority of the work that actually modifies or
+ * creates a file. It expects a filled and signed user_request
+ * structure, req, and will return the resulting FR certificate and
+ * its signature in *hmac_out. Additionally, the module's
+ * authenticated acknowledgement (equal to HMAC(req | 0), where |
+ * indicates concatenation) is output in *ack_hmac_out.
+ *
+ * If the request is to modify the file, the parameters
+ * encrypted_secret, kf, encrypted_contents, and contents_len are used
+ * (otherwise they are ignored). `encrypted_secret' should be the file
+ * encryption key XOR'd with HMAC(file index | file counter,
+ * user_key). kf should be HMAC(encryption secret, file index).
+ */
struct tm_cert sp_request(struct service_provider *sp,
const struct user_request *req, hash_t req_hmac,
hash_t *hmac_out,
struct tm_cert *vr_out, hash_t *vr_hmac_out,
- hash_t *ack_hmac_out)
+ hash_t *ack_hmac_out,
+ hash_t encrypted_secret, hash_t kf,
+ const void *encrypted_contents,
+ size_t contents_len)
{
struct tm_cert vr = cert_null;
hash_t vr_hmac, ack_hmac, fr_hmac;
@@ -325,13 +345,51 @@ struct tm_cert sp_request(struct service_provider *sp,
need_insert = true;
}
- rec->version = fr.fr.version;
rec->counter = fr.fr.counter;
rec->fr_cert = fr;
rec->fr_hmac = fr_hmac;
+ if(rec->version != fr.fr.version)
+ {
+ rec->version = fr.fr.version;
+
+ struct file_version ver;
+ hash_t gamma = sha256(encrypted_contents, contents_len);
+ ver.l = hmac_sha256(&gamma, sizeof(gamma),
+ &kf, sizeof(kf));
+
+ if(!is_zero(encrypted_secret) && !is_zero(kf))
+ {
+ /* File is encrypted */
+ ver.encrypted_secret = tm_verify_and_encrypt_secret(sp->tm,
+ rec->idx, rec->counter,
+ req->user_id,
+ encrypted_secret, kf);
+ assert(!is_zero(ver.encrypted_secret));
+
+ /* We have no way of verifying that kf=HMAC(encryption
+ * secret, file index) ourselves; instead we rely on the
+ * module to do so for us. */
+ ver.kf = kf;
+ }
+ else
+ {
+ ver.encrypted_secret = hash_null;
+ }
+
+ ver.vr_cert = vr;
+ ver.vr_hmac = vr_hmac;
+
+ append_version(rec, &ver);
+ }
+
if(need_insert)
- insert_record(sp, rec);
+ {
+ append_record(sp, rec);
+
+ /* append_record will make a copy */
+ free(rec);
+ }
/* update our tree */
sp->mt_leaves[req->idx - 1].val = u64_to_hash(fr.fr.counter);
@@ -371,7 +429,8 @@ void sp_test(void)
hash_t fr_hmac;
hash_t ack_hmac;
- struct tm_cert fr_cert = sp_request(sp, &req, req_hmac, &fr_hmac, NULL, NULL, &ack_hmac);
+ struct tm_cert fr_cert = sp_request(sp, &req, req_hmac, &fr_hmac, NULL, NULL, &ack_hmac,
+ hash_null, hash_null, NULL, 0);
check(fr_cert.type == FR &&
fr_cert.fr.counter == 1 &&
@@ -394,7 +453,8 @@ void sp_test(void)
struct tm_cert vr;
hash_t vr_hmac;
- struct tm_cert new_fr = sp_request(sp, &mod, req_hmac, &fr_hmac, &vr, &vr_hmac, &ack_hmac);
+ struct tm_cert new_fr = sp_request(sp, &mod, req_hmac, &fr_hmac, &vr, &vr_hmac, &ack_hmac,
+ hash_null, hash_null, "contents", 8);
printf("File modification: ");
check(new_fr.type == FR);
diff --git a/service_provider.h b/service_provider.h
index 883c9ea..6deb814 100644
--- a/service_provider.h
+++ b/service_provider.h
@@ -10,11 +10,16 @@
struct service_provider;
struct service_provider *sp_new(const void *key, size_t keylen, int logleaves);
+
+/* see .c file for documentation */
struct tm_cert sp_request(struct service_provider *sp,
const struct user_request *req, hash_t req_hmac,
hash_t *hmac_out,
- struct tm_cert *vr_out, hash_t *vr_hmac,
- hash_t *ack_hmac);
+ struct tm_cert *vr_out, hash_t *vr_hmac_out,
+ hash_t *ack_hmac_out,
+ hash_t encrypted_secret, hash_t kf,
+ const void *encrypted_contents,
+ size_t contents_len);
void sp_test(void);
diff --git a/trusted_module.c b/trusted_module.c
index 47bcfa2..b3db5b2 100644
--- a/trusted_module.c
+++ b/trusted_module.c
@@ -674,9 +674,9 @@ hash_t tm_verify_and_encrypt_secret(const struct trusted_module *tm,
uint64_t file_idx,
uint64_t file_counter,
uint64_t user_id,
- hash_t enc_secret, hash_t kf)
+ hash_t encrypted_secret, hash_t kf)
{
- hash_t pad; /* key = enc_secret ^ pad */
+ hash_t pad; /* key = encrypted_secret ^ pad */
HMAC_CTX *ctx = HMAC_CTX_new();
HMAC_Init_ex(ctx, tm->user_keys[user_id - 1].key, tm->user_keys[user_id - 1].len,
EVP_sha256(), NULL);
@@ -687,7 +687,7 @@ hash_t tm_verify_and_encrypt_secret(const struct trusted_module *tm,
HMAC_Final(ctx, pad.hash, NULL);
HMAC_CTX_free(ctx);
- hash_t key = hash_xor(enc_secret, pad);
+ hash_t key = hash_xor(encrypted_secret, pad);
if(hash_equals(kf,
hmac_sha256(key.hash, sizeof(key.hash),
diff --git a/trusted_module.h b/trusted_module.h
index 71d086e..8cdf65a 100644
--- a/trusted_module.h
+++ b/trusted_module.h
@@ -55,7 +55,10 @@ struct user_request {
uint64_t counter; /* current counter value, 0 for creation */
hash_t val; /* for ACL update, val=[root of ACL IOMT], for file
* update, val is a commitment to the contents, key,
- * and index of the file */
+ * and index of the file (specifically this is the
+ * value represented by lambda in Mohanty et al.,
+ * equal to HMAC(h(encrypted contents), kf). Note that
+ * kf=HMAC(key, file_idx) */
union {
/* if counter = 0 and type = ACL_UPDATE, create a new file with given ACL */
struct {
@@ -155,4 +158,29 @@ struct tm_cert tm_request(struct trusted_module *tm,
struct tm_cert *vr_out, hash_t *vr_hmac,
hash_t *ack_hmac);
+/* enc_secret is encrypted by the user by XOR'ing the file encryption
+ * key with h(f + c_f + K), where + denotes concatenation. The purpose
+ * of this function is to decrypt the secret passed by the user,
+ * verify its integrity against kf=HMAC(secret, key=f_idx), and then
+ * re-encrypt the secret with the module's secret key. This is the
+ * F_rs() function described by Mohanty et al. */
+/* Untested. */
+hash_t tm_verify_and_encrypt_secret(const struct trusted_module *tm,
+ uint64_t file_idx,
+ uint64_t file_counter,
+ uint64_t user_id,
+ hash_t encrypted_secret, hash_t kf);
+
+/* Decrypt a previously encrypted secret, and then encrypt for receipt
+ * by a user. rv1 should bind the file index and counter to the
+ * current root. rv2 should verify the user's access level in the
+ * ACL. The index (which is a user id) given in rv2 will select the
+ * key used to encrypt the secret. As with
+ * tm_verify_and_encrypt_secret(), kf=HMAC(secret, key=f_idx). */
+/* Untested. */
+hash_t tm_retrieve_secret(const struct trusted_module *tm,
+ const struct tm_cert *rv1, hash_t rv1_hmac,
+ const struct tm_cert *rv2, hash_t rv2_hmac,
+ const struct tm_cert *fr, hash_t fr_hmac,
+ hash_t secret, hash_t kf);
#endif