aboutsummaryrefslogtreecommitdiff
path: root/helper.c
blob: 1646c1e1653ae57a6232555fbcbd1cd781e6bfe6 (plain)
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
/* Functions to help with certificate generation (untrusted). */

/* Some of the certificate generation routines require multiple other
 * certificates to function. This file provides various helper
 * functions to handle the generation of these needed certificates. */

#include <assert.h>

#include "crypto.h"
#include "trusted_module.h"

struct tm_cert cert_ru(const struct trusted_module *tm,
                       const struct iomt_node *node, hash_t new_val,
                       const hash_t *comp, const int *orders, size_t n,
                       hash_t *hmac_out)
{
    struct iomt_node new_node = *node;
    new_node.val = new_val;
    hash_t nu_hmac;
    struct tm_cert nu = tm_cert_node_update(tm,
                                            hash_node(node),
                                            hash_node(&new_node),
                                            comp, orders, n,
                                            &nu_hmac);

    return tm_cert_record_update(tm, &nu, nu_hmac, node, new_val, hmac_out);
}

struct tm_cert cert_rv(const struct trusted_module *tm,
                       const struct iomt_node *node,
                       const hash_t *comp, const int *orders, size_t n,
                       hash_t *hmac_out,
                       uint64_t b,
                       struct tm_cert *nonexist, hash_t *hmac_nonexist)
{
    hash_t nu_hmac;
    struct tm_cert nu = tm_cert_node_update(tm,
                                            hash_node(node),
                                            hash_node(node),
                                            comp, orders, n,
                                            &nu_hmac);

    return tm_cert_record_verify(tm,
                                 &nu, nu_hmac,
                                 node,
                                 hmac_out,
                                 b, nonexist, hmac_nonexist);
}

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)
{
    /* construct a request to create a file */
    struct user_request req;
    req.idx = file_node->idx;
    req.user_id = user_id;
    req.type = ACL_UPDATE;
    req.counter = 0;

    /* construct ACL with a single element (the user, with full access) */
    struct iomt_node acl_node = (struct iomt_node) { 1, 1, u64_to_hash(3) };
    req.val = merkle_compute(hash_node(&acl_node), NULL, NULL, 0);

    hash_t one = u64_to_hash(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(tm,
                                file_node, one,
                                file_comp, file_orders, file_n,
                                &ru_hmac);

    req.create.ru_cert = ru;
    req.create.ru_hmac = ru_hmac;

    return req;
}

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,
                                   const hash_t *file_comp, const int *file_orders, size_t file_n,
                                   const struct iomt_node *acl_node,
                                   const hash_t *acl_comp, const int *acl_orders, size_t acl_n,
                                   hash_t fileval)
{
    /* modification */
    struct user_request req;
    req.type = FILE_UPDATE;

    req.idx = file_node->idx;
    req.counter = hash_to_u64(file_node->val);

    req.user_id = acl_node->idx;

    req.modify.fr_cert = *fr_cert;
    req.modify.fr_hmac = fr_hmac;

    req.modify.rv_cert = cert_rv(tm,
                                 acl_node,
                                 acl_comp, acl_orders, acl_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 = fileval;

    return req;
}