Commit | Line | Data |
---|---|---|
adf53a77 RS |
1 | /* |
2 | * Copyright (C) 2013 Politecnico di Torino, Italy | |
3 | * TORSEC group -- http://security.polito.it | |
4 | * | |
5 | * Author: Roberto Sassu <roberto.sassu@polito.it> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation, version 2 of the | |
10 | * License. | |
11 | * | |
12 | * File: ima_template.c | |
13 | * Helpers to manage template descriptors. | |
14 | */ | |
9b9d4ce5 RS |
15 | #include <crypto/hash_info.h> |
16 | ||
adf53a77 | 17 | #include "ima.h" |
3ce1217d | 18 | #include "ima_template_lib.h" |
adf53a77 RS |
19 | |
20 | static struct ima_template_desc defined_templates[] = { | |
4d7aeee7 RS |
21 | {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, |
22 | {.name = "ima-ng",.fmt = "d-ng|n-ng"}, | |
bcbc9b0c | 23 | {.name = "ima-sig",.fmt = "d-ng|n-ng|sig"}, |
adf53a77 RS |
24 | }; |
25 | ||
26 | static struct ima_template_field supported_fields[] = { | |
3ce1217d RS |
27 | {.field_id = "d",.field_init = ima_eventdigest_init, |
28 | .field_show = ima_show_template_digest}, | |
29 | {.field_id = "n",.field_init = ima_eventname_init, | |
30 | .field_show = ima_show_template_string}, | |
4d7aeee7 RS |
31 | {.field_id = "d-ng",.field_init = ima_eventdigest_ng_init, |
32 | .field_show = ima_show_template_digest_ng}, | |
33 | {.field_id = "n-ng",.field_init = ima_eventname_ng_init, | |
34 | .field_show = ima_show_template_string}, | |
bcbc9b0c MZ |
35 | {.field_id = "sig",.field_init = ima_eventsig_init, |
36 | .field_show = ima_show_template_sig}, | |
adf53a77 RS |
37 | }; |
38 | ||
a71dc65d | 39 | static struct ima_template_desc *ima_template; |
9b9d4ce5 RS |
40 | static struct ima_template_desc *lookup_template_desc(const char *name); |
41 | ||
42 | static int __init ima_template_setup(char *str) | |
43 | { | |
44 | struct ima_template_desc *template_desc; | |
45 | int template_len = strlen(str); | |
46 | ||
47 | /* | |
48 | * Verify that a template with the supplied name exists. | |
49 | * If not, use CONFIG_IMA_DEFAULT_TEMPLATE. | |
50 | */ | |
51 | template_desc = lookup_template_desc(str); | |
52 | if (!template_desc) | |
53 | return 1; | |
54 | ||
55 | /* | |
56 | * Verify whether the current hash algorithm is supported | |
57 | * by the 'ima' template. | |
58 | */ | |
59 | if (template_len == 3 && strcmp(str, IMA_TEMPLATE_IMA_NAME) == 0 && | |
60 | ima_hash_algo != HASH_ALGO_SHA1 && ima_hash_algo != HASH_ALGO_MD5) { | |
61 | pr_err("IMA: template does not support hash alg\n"); | |
62 | return 1; | |
63 | } | |
64 | ||
65 | ima_template = template_desc; | |
66 | return 1; | |
67 | } | |
68 | __setup("ima_template=", ima_template_setup); | |
a71dc65d RS |
69 | |
70 | static struct ima_template_desc *lookup_template_desc(const char *name) | |
71 | { | |
72 | int i; | |
73 | ||
74 | for (i = 0; i < ARRAY_SIZE(defined_templates); i++) { | |
75 | if (strcmp(defined_templates[i].name, name) == 0) | |
76 | return defined_templates + i; | |
77 | } | |
78 | ||
79 | return NULL; | |
80 | } | |
81 | ||
3ce1217d | 82 | static struct ima_template_field *lookup_template_field(const char *field_id) |
adf53a77 RS |
83 | { |
84 | int i; | |
85 | ||
86 | for (i = 0; i < ARRAY_SIZE(supported_fields); i++) | |
87 | if (strncmp(supported_fields[i].field_id, field_id, | |
88 | IMA_TEMPLATE_FIELD_ID_MAX_LEN) == 0) | |
89 | return &supported_fields[i]; | |
90 | return NULL; | |
91 | } | |
92 | ||
dbc335d2 | 93 | static int template_fmt_size(const char *template_fmt) |
adf53a77 RS |
94 | { |
95 | char c; | |
96 | int template_fmt_len = strlen(template_fmt); | |
97 | int i = 0, j = 0; | |
98 | ||
99 | while (i < template_fmt_len) { | |
100 | c = template_fmt[i]; | |
101 | if (c == '|') | |
102 | j++; | |
103 | i++; | |
104 | } | |
105 | ||
106 | return j + 1; | |
107 | } | |
108 | ||
dbc335d2 | 109 | static int template_desc_init_fields(const char *template_fmt, |
adf53a77 RS |
110 | struct ima_template_field ***fields, |
111 | int *num_fields) | |
112 | { | |
af91706d | 113 | char *c, *template_fmt_copy, *template_fmt_ptr; |
3ce1217d | 114 | int template_num_fields = template_fmt_size(template_fmt); |
adf53a77 RS |
115 | int i, result = 0; |
116 | ||
117 | if (template_num_fields > IMA_TEMPLATE_NUM_FIELDS_MAX) | |
118 | return -EINVAL; | |
119 | ||
dbc335d2 RS |
120 | /* copying is needed as strsep() modifies the original buffer */ |
121 | template_fmt_copy = kstrdup(template_fmt, GFP_KERNEL); | |
122 | if (template_fmt_copy == NULL) | |
123 | return -ENOMEM; | |
124 | ||
adf53a77 RS |
125 | *fields = kzalloc(template_num_fields * sizeof(*fields), GFP_KERNEL); |
126 | if (*fields == NULL) { | |
127 | result = -ENOMEM; | |
128 | goto out; | |
129 | } | |
af91706d RS |
130 | |
131 | template_fmt_ptr = template_fmt_copy; | |
132 | for (i = 0; (c = strsep(&template_fmt_ptr, "|")) != NULL && | |
adf53a77 | 133 | i < template_num_fields; i++) { |
3ce1217d | 134 | struct ima_template_field *f = lookup_template_field(c); |
adf53a77 RS |
135 | |
136 | if (!f) { | |
137 | result = -ENOENT; | |
138 | goto out; | |
139 | } | |
140 | (*fields)[i] = f; | |
141 | } | |
142 | *num_fields = i; | |
adf53a77 | 143 | out: |
dbc335d2 RS |
144 | if (result < 0) { |
145 | kfree(*fields); | |
146 | *fields = NULL; | |
147 | } | |
148 | kfree(template_fmt_copy); | |
adf53a77 RS |
149 | return result; |
150 | } | |
151 | ||
152 | static int init_defined_templates(void) | |
153 | { | |
154 | int i = 0; | |
155 | int result = 0; | |
156 | ||
157 | /* Init defined templates. */ | |
158 | for (i = 0; i < ARRAY_SIZE(defined_templates); i++) { | |
159 | struct ima_template_desc *template = &defined_templates[i]; | |
160 | ||
161 | result = template_desc_init_fields(template->fmt, | |
162 | &(template->fields), | |
163 | &(template->num_fields)); | |
164 | if (result < 0) | |
165 | return result; | |
166 | } | |
167 | return result; | |
168 | } | |
169 | ||
a71dc65d RS |
170 | struct ima_template_desc *ima_template_desc_current(void) |
171 | { | |
172 | if (!ima_template) | |
4286587d MZ |
173 | ima_template = |
174 | lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE); | |
a71dc65d RS |
175 | return ima_template; |
176 | } | |
177 | ||
adf53a77 RS |
178 | int ima_init_template(void) |
179 | { | |
180 | int result; | |
181 | ||
182 | result = init_defined_templates(); | |
183 | if (result < 0) | |
184 | return result; | |
185 | ||
186 | return 0; | |
187 | } |