diff options
author | Franklin Wei <me@fwei.tk> | 2018-06-16 17:01:38 -0400 |
---|---|---|
committer | Franklin Wei <me@fwei.tk> | 2018-06-16 17:01:38 -0400 |
commit | a0594b1723f947db0fd8b25a482320617310e878 (patch) | |
tree | d051de590893aa6366f5b85ea5b7f2eeecc797ab | |
parent | 64c1c7bd12eab99897cbdfcdeb8bdd5ad7fc1ac6 (diff) | |
download | csaa-a0594b1723f947db0fd8b25a482320617310e878.zip csaa-a0594b1723f947db0fd8b25a482320617310e878.tar.gz csaa-a0594b1723f947db0fd8b25a482320617310e878.tar.bz2 csaa-a0594b1723f947db0fd8b25a482320617310e878.tar.xz |
Implement F_snd() IVP (untested) and add some performance tests to sp_test()
-rw-r--r-- | service_provider.c | 39 | ||||
-rw-r--r-- | service_provider.h | 2 | ||||
-rw-r--r-- | trusted_module.c | 104 | ||||
-rw-r--r-- | trusted_module.h | 18 |
4 files changed, 151 insertions, 12 deletions
diff --git a/service_provider.c b/service_provider.c index 6d69010..e136917 100644 --- a/service_provider.c +++ b/service_provider.c @@ -396,7 +396,7 @@ struct user_request sp_createfile(struct service_provider *sp, struct user_request sp_modifyfile(struct service_provider *sp, uint64_t user_id, const void *key, size_t keylen, uint64_t file_idx, - hash_t encrypted_secret, + hash_t encrypted_secret, hash_t kf, const void *encrypted_file, size_t filelen, hash_t *ack_hmac) { @@ -442,8 +442,17 @@ struct user_request sp_modifyfile(struct service_provider *sp, struct tm_cert vr; hash_t vr_hmac, fr_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, NULL); + struct tm_cert new_fr = sp_request(sp, + &mod, req_hmac, + &fr_hmac, + &vr, &vr_hmac, + ack_hmac, + encrypted_secret, kf, + encrypted_file, filelen, + NULL); + + /* We return the request because that is how the module's + * authentication is done. */ if(new_fr.type == FR) return mod; return req_null; @@ -457,11 +466,17 @@ static bool ack_verify(const struct user_request *req, return hash_equals(hmac, correct); } +#include <time.h> + void sp_test(void) { - /* 2^10 = 1024 leaves ought to be enough for anybody */ - int logleaves = 10; + int logleaves = 4; + printf("Initializing IOMT with %llu nodes.\n", 1ULL << logleaves); + + clock_t start = clock(); struct service_provider *sp = sp_new("a", 1, logleaves); + clock_t stop = clock(); + printf("%.1f placeholder insertions per second\n", (double)(1ULL << logleaves) * CLOCKS_PER_SEC / (stop - start)); check("Tree initialization", sp != NULL); @@ -470,12 +485,20 @@ void sp_test(void) check("File creation", ack_verify(&req, "a", 1, ack_hmac)); - req = sp_modifyfile(sp, 1, "a", 1, 1, hash_null, NULL, 0, &ack_hmac); +#define N_MODIFY 1000 + start = clock(); + for(int i = 0; i < N_MODIFY; ++i) + req = sp_modifyfile(sp, 1, "a", 1, 1, hash_null, hash_null, NULL, 0, &ack_hmac); + stop = clock(); + printf("%.1f modifications per second\n", (double)N_MODIFY * CLOCKS_PER_SEC / (stop - start)); check("File modification", ack_verify(&req, "a", 1, ack_hmac)); - printf("CDI-IOMT contents: "); - iomt_dump(sp->iomt); + if(logleaves < 5) + { + printf("CDI-IOMT contents: "); + iomt_dump(sp->iomt); + } /* test tree initilization (only simple case) */ if(logleaves == 1) diff --git a/service_provider.h b/service_provider.h index e6180b1..2529af9 100644 --- a/service_provider.h +++ b/service_provider.h @@ -32,7 +32,7 @@ struct user_request sp_createfile(struct service_provider *sp, struct user_request sp_modifyfile(struct service_provider *sp, uint64_t user_id, const void *key, size_t keylen, uint64_t file_idx, - hash_t encrypted_secret, + hash_t encrypted_secret, hash_t kf, const void *encrypted_file, size_t filelen, hash_t *ack_hmac); diff --git a/trusted_module.c b/trusted_module.c index f9f0472..e55cf3e 100644 --- a/trusted_module.c +++ b/trusted_module.c @@ -37,7 +37,7 @@ struct trusted_module { static void tm_setroot(struct trusted_module *tm, hash_t newroot) { - printf("TM: %s -> %s\n", hash_format(tm->root, 4).str, hash_format(newroot, 4).str); + //printf("TM: %s -> %s\n", hash_format(tm->root, 4).str, hash_format(newroot, 4).str); tm->root = newroot; } @@ -246,7 +246,7 @@ struct tm_cert tm_cert_equiv(const struct trusted_module *tm, /* nu must be of the form [x,y,x,y] to indicate that x is a child of y */ /* also, if b > 0 and nonexist != NULL, this function will generate a * certificate indicating that no node with index b exists with root - * y*/ + * y */ struct tm_cert tm_cert_record_verify(const struct trusted_module *tm, const struct tm_cert *nu, hash_t hmac, const struct iomt_node *node, @@ -806,6 +806,106 @@ hash_t tm_retrieve_secret(const struct trusted_module *tm, return hash_xor(secret, pad); } +static hash_t sign_response(const struct trusted_module *tm, + const struct version_info *ver, + uint64_t user_id) +{ + return hmac_sha256(ver, sizeof(*ver), + tm->user_keys[user_id - 1].key, + tm->user_keys[user_id - 1].len); +} + +/* Verify the integrity of file information passed in the four + * certificates by checking it against the current root; response is + * authenticated with HMAC(response, user_key). RV1 should verify the + * current file counter value against the current root. RV2 should + * prove that the user has the proper access level in the ACL. VR + * should be signed and can be any version (not just the latest + * one). Finally, FR should be the latest file record certificate + * issued by the module, reflecting the latest counter value and + * ACL. */ +struct version_info tm_verify_file(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, + const struct tm_cert *vr, hash_t vr_hmac, + hash_t *response_hmac) +{ + struct version_info verinfo = verinfo_null; + + /* No authenticated response if the parameters are incorrect or + * improperly signed; it is the service provider's responsibility + * to make sure these are correct, because if they are not, the + * user will not receive the expected authentication. */ + if(!rv1 || !rv2 || !fr || !vr) + { + tm_seterror("null paramter"); + return verinfo_null; + } + + if(!cert_verify(tm, rv1, rv1_hmac) || + !cert_verify(tm, rv2, rv2_hmac) || + !cert_verify(tm, fr, fr_hmac) || + !cert_verify(tm, vr, vr_hmac)) + + { + tm_seterror("certificate signature invalid"); + return verinfo_null; + } + + /* Prepare the denial response now so we can fail if needed. */ + verinfo.idx = fr->fr.idx; + *response_hmac = sign_response(tm, &verinfo, rv2->rv.idx); + + /* Check RV1 against root */ + if(!hash_equals(rv1->rv.root, tm->root)) + { + tm_seterror("RV1 does not reflect current root"); + return verinfo; + } + + /* Ensure that all file indices match */ + if(rv1->rv.idx != fr->fr.idx || + rv1->rv.idx != vr->vr.idx) + { + tm_seterror("certificate indices do not match"); + return verinfo; + } + + /* Ensure that the FR certificate is fresh by checking the counter + * against the value of RV1 (which is guaranteed to be fresh) */ + if(hash_to_u64(rv1->rv.val) != fr->fr.counter) + { + tm_seterror("FR counter is not fresh"); + return verinfo; + } + + /* Make sure that RV2's root is the file ACL */ + if(!hash_equals(rv2->rv.root, fr->fr.acl)) + { + tm_seterror("RV2 does not have file ACL as root"); + return verinfo; + } + + /* Check whether file exists and that the access level is sufficient */ + if(is_zero(rv1->rv.val) || + hash_to_u64(rv2->rv.val) < 1) + { + tm_seterror("insufficient permissions or file does not exist"); + return verinfo; + } + + /* We have verified that the file exists and can convey this to + * the user */ + verinfo.counter = fr->fr.counter; + verinfo.max_version = fr->fr.version; + verinfo.version = vr->vr.version; + verinfo.lambda = vr->vr.hash; + + *response_hmac = sign_response(tm, &verinfo, rv2->rv.idx); + return verinfo; +} + /* self-test */ void tm_test(void) { diff --git a/trusted_module.h b/trusted_module.h index 27dc8ec..1aab731 100644 --- a/trusted_module.h +++ b/trusted_module.h @@ -43,7 +43,8 @@ struct tm_cert { struct { uint64_t idx; uint64_t version; - hash_t hash; /* commitment to contents, key, and index */ + hash_t hash; /* lambda value: the commitment to contents, + * key, and index */ } vr; /* version record (of a file) */ }; }; @@ -85,8 +86,16 @@ struct user_request { }; }; +struct version_info { + uint64_t idx; + uint64_t counter; + uint64_t version, max_version; + hash_t lambda; /* equal to HMAC(h(encrypted_contents), key=HMAC(key, file_idx)) */ +}; + static const struct user_request req_null = { REQ_NONE }; static const struct tm_cert cert_null = { CERT_NONE }; +static const struct version_info verinfo_null = { 0 }; /* creates 1 user with given shared secret */ struct trusted_module *tm_new(const void *key, size_t keylen); @@ -185,6 +194,13 @@ hash_t tm_retrieve_secret(const struct trusted_module *tm, const struct tm_cert *fr, hash_t fr_hmac, hash_t secret, hash_t kf); +struct version_info tm_verify_file(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, + const struct tm_cert *vr, hash_t vr_hmac, + hash_t *response_hmac); + hash_t ack_sign(const struct user_request *req, const void *key, size_t keylen); const char *tm_geterror(void); |