2 * Copyright (C) 2013 Politecnico di Torino, Italy
3 * TORSEC group -- http://security.polito.it
5 * Author: Roberto Sassu <roberto.sassu@polito.it>
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
12 * File: ima_template.c
13 * Helpers to manage template descriptors.
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 #include <linux/rculist.h>
20 #include "ima_template_lib.h"
22 enum header_fields
{ HDR_PCR
, HDR_DIGEST
, HDR_TEMPLATE_NAME
,
23 HDR_TEMPLATE_DATA
, HDR__LAST
};
25 static struct ima_template_desc builtin_templates
[] = {
26 {.name
= IMA_TEMPLATE_IMA_NAME
, .fmt
= IMA_TEMPLATE_IMA_FMT
},
27 {.name
= "ima-ng", .fmt
= "d-ng|n-ng"},
28 {.name
= "ima-sig", .fmt
= "d-ng|n-ng|sig"},
29 {.name
= "", .fmt
= ""}, /* placeholder for a custom format */
32 static LIST_HEAD(defined_templates
);
33 static DEFINE_SPINLOCK(template_list
);
35 static struct ima_template_field supported_fields
[] = {
36 {.field_id
= "d", .field_init
= ima_eventdigest_init
,
37 .field_show
= ima_show_template_digest
},
38 {.field_id
= "n", .field_init
= ima_eventname_init
,
39 .field_show
= ima_show_template_string
},
40 {.field_id
= "d-ng", .field_init
= ima_eventdigest_ng_init
,
41 .field_show
= ima_show_template_digest_ng
},
42 {.field_id
= "n-ng", .field_init
= ima_eventname_ng_init
,
43 .field_show
= ima_show_template_string
},
44 {.field_id
= "sig", .field_init
= ima_eventsig_init
,
45 .field_show
= ima_show_template_sig
},
47 #define MAX_TEMPLATE_NAME_LEN 15
49 static struct ima_template_desc
*ima_template
;
50 static struct ima_template_desc
*lookup_template_desc(const char *name
);
51 static int template_desc_init_fields(const char *template_fmt
,
52 struct ima_template_field
***fields
,
55 static int __init
ima_template_setup(char *str
)
57 struct ima_template_desc
*template_desc
;
58 int template_len
= strlen(str
);
63 ima_init_template_list();
66 * Verify that a template with the supplied name exists.
67 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
69 template_desc
= lookup_template_desc(str
);
71 pr_err("template %s not found, using %s\n",
72 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
77 * Verify whether the current hash algorithm is supported
78 * by the 'ima' template.
80 if (template_len
== 3 && strcmp(str
, IMA_TEMPLATE_IMA_NAME
) == 0 &&
81 ima_hash_algo
!= HASH_ALGO_SHA1
&& ima_hash_algo
!= HASH_ALGO_MD5
) {
82 pr_err("template does not support hash alg\n");
86 ima_template
= template_desc
;
89 __setup("ima_template=", ima_template_setup
);
91 static int __init
ima_template_fmt_setup(char *str
)
93 int num_templates
= ARRAY_SIZE(builtin_templates
);
98 if (template_desc_init_fields(str
, NULL
, NULL
) < 0) {
99 pr_err("format string '%s' not valid, using template %s\n",
100 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
104 builtin_templates
[num_templates
- 1].fmt
= str
;
105 ima_template
= builtin_templates
+ num_templates
- 1;
109 __setup("ima_template_fmt=", ima_template_fmt_setup
);
111 static struct ima_template_desc
*lookup_template_desc(const char *name
)
113 struct ima_template_desc
*template_desc
;
117 list_for_each_entry_rcu(template_desc
, &defined_templates
, list
) {
118 if ((strcmp(template_desc
->name
, name
) == 0) ||
119 (strcmp(template_desc
->fmt
, name
) == 0)) {
125 return found
? template_desc
: NULL
;
128 static struct ima_template_field
*lookup_template_field(const char *field_id
)
132 for (i
= 0; i
< ARRAY_SIZE(supported_fields
); i
++)
133 if (strncmp(supported_fields
[i
].field_id
, field_id
,
134 IMA_TEMPLATE_FIELD_ID_MAX_LEN
) == 0)
135 return &supported_fields
[i
];
139 static int template_fmt_size(const char *template_fmt
)
142 int template_fmt_len
= strlen(template_fmt
);
145 while (i
< template_fmt_len
) {
155 static int template_desc_init_fields(const char *template_fmt
,
156 struct ima_template_field
***fields
,
159 const char *template_fmt_ptr
;
160 struct ima_template_field
*found_fields
[IMA_TEMPLATE_NUM_FIELDS_MAX
];
161 int template_num_fields
;
164 if (num_fields
&& *num_fields
> 0) /* already initialized? */
167 template_num_fields
= template_fmt_size(template_fmt
);
169 if (template_num_fields
> IMA_TEMPLATE_NUM_FIELDS_MAX
) {
170 pr_err("format string '%s' contains too many fields\n",
175 for (i
= 0, template_fmt_ptr
= template_fmt
; i
< template_num_fields
;
176 i
++, template_fmt_ptr
+= len
+ 1) {
177 char tmp_field_id
[IMA_TEMPLATE_FIELD_ID_MAX_LEN
+ 1];
179 len
= strchrnul(template_fmt_ptr
, '|') - template_fmt_ptr
;
180 if (len
== 0 || len
> IMA_TEMPLATE_FIELD_ID_MAX_LEN
) {
181 pr_err("Invalid field with length %d\n", len
);
185 memcpy(tmp_field_id
, template_fmt_ptr
, len
);
186 tmp_field_id
[len
] = '\0';
187 found_fields
[i
] = lookup_template_field(tmp_field_id
);
188 if (!found_fields
[i
]) {
189 pr_err("field '%s' not found\n", tmp_field_id
);
194 if (fields
&& num_fields
) {
195 *fields
= kmalloc_array(i
, sizeof(*fields
), GFP_KERNEL
);
199 memcpy(*fields
, found_fields
, i
* sizeof(*fields
));
206 void ima_init_template_list(void)
210 if (!list_empty(&defined_templates
))
213 spin_lock(&template_list
);
214 for (i
= 0; i
< ARRAY_SIZE(builtin_templates
); i
++) {
215 list_add_tail_rcu(&builtin_templates
[i
].list
,
218 spin_unlock(&template_list
);
221 struct ima_template_desc
*ima_template_desc_current(void)
224 ima_init_template_list();
226 lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE
);
231 int __init
ima_init_template(void)
233 struct ima_template_desc
*template = ima_template_desc_current();
236 result
= template_desc_init_fields(template->fmt
,
238 &(template->num_fields
));
240 pr_err("template %s init failed, result: %d\n",
241 (strlen(template->name
) ?
242 template->name
: template->fmt
), result
);
247 static struct ima_template_desc
*restore_template_fmt(char *template_name
)
249 struct ima_template_desc
*template_desc
= NULL
;
252 ret
= template_desc_init_fields(template_name
, NULL
, NULL
);
254 pr_err("attempting to initialize the template \"%s\" failed\n",
259 template_desc
= kzalloc(sizeof(*template_desc
), GFP_KERNEL
);
263 template_desc
->name
= "";
264 template_desc
->fmt
= kstrdup(template_name
, GFP_KERNEL
);
265 if (!template_desc
->fmt
)
268 spin_lock(&template_list
);
269 list_add_tail_rcu(&template_desc
->list
, &defined_templates
);
270 spin_unlock(&template_list
);
272 return template_desc
;
275 static int ima_restore_template_data(struct ima_template_desc
*template_desc
,
277 int template_data_size
,
278 struct ima_template_entry
**entry
)
283 *entry
= kzalloc(sizeof(**entry
) +
284 template_desc
->num_fields
* sizeof(struct ima_field_data
),
289 ret
= ima_parse_buf(template_data
, template_data
+ template_data_size
,
290 NULL
, template_desc
->num_fields
,
291 (*entry
)->template_data
, NULL
, NULL
,
292 ENFORCE_FIELDS
| ENFORCE_BUFEND
, "template data");
298 (*entry
)->template_desc
= template_desc
;
299 for (i
= 0; i
< template_desc
->num_fields
; i
++) {
300 struct ima_field_data
*field_data
= &(*entry
)->template_data
[i
];
301 u8
*data
= field_data
->data
;
303 (*entry
)->template_data
[i
].data
=
304 kzalloc(field_data
->len
+ 1, GFP_KERNEL
);
305 if (!(*entry
)->template_data
[i
].data
) {
309 memcpy((*entry
)->template_data
[i
].data
, data
, field_data
->len
);
310 (*entry
)->template_data_len
+= sizeof(field_data
->len
);
311 (*entry
)->template_data_len
+= field_data
->len
;
315 ima_free_template_entry(*entry
);
322 /* Restore the serialized binary measurement list without extending PCRs. */
323 int ima_restore_measurement_list(loff_t size
, void *buf
)
325 char template_name
[MAX_TEMPLATE_NAME_LEN
];
327 struct ima_kexec_hdr
*khdr
= buf
;
328 struct ima_field_data hdr
[HDR__LAST
] = {
329 [HDR_PCR
] = {.len
= sizeof(u32
)},
330 [HDR_DIGEST
] = {.len
= TPM_DIGEST_SIZE
},
333 void *bufp
= buf
+ sizeof(*khdr
);
335 struct ima_template_entry
*entry
;
336 struct ima_template_desc
*template_desc
;
337 DECLARE_BITMAP(hdr_mask
, HDR__LAST
);
338 unsigned long count
= 0;
341 if (!buf
|| size
< sizeof(*khdr
))
344 if (ima_canonical_fmt
) {
345 khdr
->version
= le16_to_cpu(khdr
->version
);
346 khdr
->count
= le64_to_cpu(khdr
->count
);
347 khdr
->buffer_size
= le64_to_cpu(khdr
->buffer_size
);
350 if (khdr
->version
!= 1) {
351 pr_err("attempting to restore a incompatible measurement list");
355 if (khdr
->count
> ULONG_MAX
- 1) {
356 pr_err("attempting to restore too many measurements");
360 bitmap_zero(hdr_mask
, HDR__LAST
);
361 bitmap_set(hdr_mask
, HDR_PCR
, 1);
362 bitmap_set(hdr_mask
, HDR_DIGEST
, 1);
365 * ima kexec buffer prefix: version, buffer size, count
366 * v1 format: pcr, digest, template-name-len, template-name,
367 * template-data-size, template-data
369 bufendp
= buf
+ khdr
->buffer_size
;
370 while ((bufp
< bufendp
) && (count
++ < khdr
->count
)) {
371 int enforce_mask
= ENFORCE_FIELDS
;
373 enforce_mask
|= (count
== khdr
->count
) ? ENFORCE_BUFEND
: 0;
374 ret
= ima_parse_buf(bufp
, bufendp
, &bufp
, HDR__LAST
, hdr
, NULL
,
375 hdr_mask
, enforce_mask
, "entry header");
379 if (hdr
[HDR_TEMPLATE_NAME
].len
>= MAX_TEMPLATE_NAME_LEN
) {
380 pr_err("attempting to restore a template name that is too long\n");
385 /* template name is not null terminated */
386 memcpy(template_name
, hdr
[HDR_TEMPLATE_NAME
].data
,
387 hdr
[HDR_TEMPLATE_NAME
].len
);
388 template_name
[hdr
[HDR_TEMPLATE_NAME
].len
] = 0;
390 if (strcmp(template_name
, "ima") == 0) {
391 pr_err("attempting to restore an unsupported template \"%s\" failed\n",
397 template_desc
= lookup_template_desc(template_name
);
398 if (!template_desc
) {
399 template_desc
= restore_template_fmt(template_name
);
405 * Only the running system's template format is initialized
406 * on boot. As needed, initialize the other template formats.
408 ret
= template_desc_init_fields(template_desc
->fmt
,
409 &(template_desc
->fields
),
410 &(template_desc
->num_fields
));
412 pr_err("attempting to restore the template fmt \"%s\" failed\n",
418 ret
= ima_restore_template_data(template_desc
,
419 hdr
[HDR_TEMPLATE_DATA
].data
,
420 hdr
[HDR_TEMPLATE_DATA
].len
,
425 memcpy(entry
->digest
, hdr
[HDR_DIGEST
].data
,
426 hdr
[HDR_DIGEST
].len
);
427 entry
->pcr
= !ima_canonical_fmt
? *(hdr
[HDR_PCR
].data
) :
428 le32_to_cpu(*(hdr
[HDR_PCR
].data
));
429 ret
= ima_restore_measurement_entry(entry
);