1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/* implementation of a basic service provider for use with the trusted
* module */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "crypto.h"
#include "helper.h"
#include "service_provider.h"
#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) */
struct tm_cert cert; /* VR certificate */
hash_t cert_hmac;
void *contents;
size_t len;
};
struct file_record {
int version;
int counter;
struct iomt_node *acl;
int acl_nodes;
struct tm_cert fr_cert; /* issued by module */
hash_t fr_hmac;
struct file_version *versions;
int n_versions;
};
struct service_provider {
struct trusted_module *tm;
struct file_record *records;
int n_records;
struct iomt_node *mt; /* leaves of CDI-IOMT, value is counter */
int mt_nodes;
};
struct service_provider *sp_new(const void *key, size_t keylen)
{
struct service_provider *sp = calloc(1, sizeof(*sp));
sp->tm = tm_new(key, keylen);
/* everything else is already zeroed by calloc */
return sp;
}
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)
{
/* see if module succeeds; if so, update the databases */
return tm_request(sp->tm, req, req_hmac, hmac_out, vr_out, vr_hmac, ack_hmac);
}
void check(int condition);
void sp_test(void)
{
struct service_provider *sp = sp_new("a", 1);
/* construct a request to create a file */
struct user_request req;
req.idx = 1;
req.user_id = 1;
req.type = ACL_UPDATE;
req.counter = 0;
struct iomt_node acl_node;
acl_node.idx = 1;
memset(&acl_node.val, 0, sizeof(acl_node.val));
acl_node.val.hash[0] = 3; /* full access */
acl_node.next_idx = 1;
req.val = merkle_compute(hash_node(&acl_node), NULL, NULL, 0);
struct iomt_node node;
node.idx = 1;
memset(node.val.hash, 0, 32);
node.next_idx = 1;
hash_t one;
memset(one.hash, 0, 32);
one.hash[0] = 1;
hash_t ru_hmac;
/* we need a RU certificate of the form [f, 0, root, 1, new root],
* which requires a NU certificate of the form [v, root, v', new
* root], where v=h(original IOMT node) and v'=h(new IOMT node) */
struct tm_cert ru = cert_ru(sp->tm, &node, one,
NULL, NULL, 0,
&ru_hmac,
0, NULL, NULL);
printf("RU generation: ");
check(ru.type == RU &&
ru.ru.idx == 1 &&
hash_equals(ru.ru.orig_val, node.val) &&
hash_equals(ru.ru.new_val, one));
/* now create a request */
req.create.ru_cert = ru;
req.create.ru_hmac = ru_hmac;
hash_t req_hmac = hmac_sha256(&req, sizeof(req), "a", 1);
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);
printf("File creation: ");
check(fr_cert.type == FR &&
fr_cert.fr.counter == 1 &&
fr_cert.fr.version == 0);
}
|