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 static struct ima_template_desc builtin_templates
[] = {
23 {.name
= IMA_TEMPLATE_IMA_NAME
, .fmt
= IMA_TEMPLATE_IMA_FMT
},
24 {.name
= "ima-ng", .fmt
= "d-ng|n-ng"},
25 {.name
= "ima-sig", .fmt
= "d-ng|n-ng|sig"},
26 {.name
= "", .fmt
= ""}, /* placeholder for a custom format */
29 static LIST_HEAD(defined_templates
);
30 static DEFINE_SPINLOCK(template_list
);
32 static struct ima_template_field supported_fields
[] = {
33 {.field_id
= "d", .field_init
= ima_eventdigest_init
,
34 .field_show
= ima_show_template_digest
},
35 {.field_id
= "n", .field_init
= ima_eventname_init
,
36 .field_show
= ima_show_template_string
},
37 {.field_id
= "d-ng", .field_init
= ima_eventdigest_ng_init
,
38 .field_show
= ima_show_template_digest_ng
},
39 {.field_id
= "n-ng", .field_init
= ima_eventname_ng_init
,
40 .field_show
= ima_show_template_string
},
41 {.field_id
= "sig", .field_init
= ima_eventsig_init
,
42 .field_show
= ima_show_template_sig
},
44 #define MAX_TEMPLATE_NAME_LEN 15
46 static struct ima_template_desc
*ima_template
;
47 static struct ima_template_desc
*lookup_template_desc(const char *name
);
48 static int template_desc_init_fields(const char *template_fmt
,
49 struct ima_template_field
***fields
,
52 static int __init
ima_template_setup(char *str
)
54 struct ima_template_desc
*template_desc
;
55 int template_len
= strlen(str
);
60 ima_init_template_list();
63 * Verify that a template with the supplied name exists.
64 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
66 template_desc
= lookup_template_desc(str
);
68 pr_err("template %s not found, using %s\n",
69 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
74 * Verify whether the current hash algorithm is supported
75 * by the 'ima' template.
77 if (template_len
== 3 && strcmp(str
, IMA_TEMPLATE_IMA_NAME
) == 0 &&
78 ima_hash_algo
!= HASH_ALGO_SHA1
&& ima_hash_algo
!= HASH_ALGO_MD5
) {
79 pr_err("template does not support hash alg\n");
83 ima_template
= template_desc
;
86 __setup("ima_template=", ima_template_setup
);
88 static int __init
ima_template_fmt_setup(char *str
)
90 int num_templates
= ARRAY_SIZE(builtin_templates
);
95 if (template_desc_init_fields(str
, NULL
, NULL
) < 0) {
96 pr_err("format string '%s' not valid, using template %s\n",
97 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
101 builtin_templates
[num_templates
- 1].fmt
= str
;
102 ima_template
= builtin_templates
+ num_templates
- 1;
106 __setup("ima_template_fmt=", ima_template_fmt_setup
);
108 static struct ima_template_desc
*lookup_template_desc(const char *name
)
110 struct ima_template_desc
*template_desc
;
114 list_for_each_entry_rcu(template_desc
, &defined_templates
, list
) {
115 if ((strcmp(template_desc
->name
, name
) == 0) ||
116 (strcmp(template_desc
->fmt
, name
) == 0)) {
122 return found
? template_desc
: NULL
;
125 static struct ima_template_field
*lookup_template_field(const char *field_id
)
129 for (i
= 0; i
< ARRAY_SIZE(supported_fields
); i
++)
130 if (strncmp(supported_fields
[i
].field_id
, field_id
,
131 IMA_TEMPLATE_FIELD_ID_MAX_LEN
) == 0)
132 return &supported_fields
[i
];
136 static int template_fmt_size(const char *template_fmt
)
139 int template_fmt_len
= strlen(template_fmt
);
142 while (i
< template_fmt_len
) {
152 static int template_desc_init_fields(const char *template_fmt
,
153 struct ima_template_field
***fields
,
156 const char *template_fmt_ptr
;
157 struct ima_template_field
*found_fields
[IMA_TEMPLATE_NUM_FIELDS_MAX
];
158 int template_num_fields
;
161 if (num_fields
&& *num_fields
> 0) /* already initialized? */
164 template_num_fields
= template_fmt_size(template_fmt
);
166 if (template_num_fields
> IMA_TEMPLATE_NUM_FIELDS_MAX
) {
167 pr_err("format string '%s' contains too many fields\n",
172 for (i
= 0, template_fmt_ptr
= template_fmt
; i
< template_num_fields
;
173 i
++, template_fmt_ptr
+= len
+ 1) {
174 char tmp_field_id
[IMA_TEMPLATE_FIELD_ID_MAX_LEN
+ 1];
176 len
= strchrnul(template_fmt_ptr
, '|') - template_fmt_ptr
;
177 if (len
== 0 || len
> IMA_TEMPLATE_FIELD_ID_MAX_LEN
) {
178 pr_err("Invalid field with length %d\n", len
);
182 memcpy(tmp_field_id
, template_fmt_ptr
, len
);
183 tmp_field_id
[len
] = '\0';
184 found_fields
[i
] = lookup_template_field(tmp_field_id
);
185 if (!found_fields
[i
]) {
186 pr_err("field '%s' not found\n", tmp_field_id
);
191 if (fields
&& num_fields
) {
192 *fields
= kmalloc_array(i
, sizeof(*fields
), GFP_KERNEL
);
196 memcpy(*fields
, found_fields
, i
* sizeof(*fields
));
203 void ima_init_template_list(void)
207 if (!list_empty(&defined_templates
))
210 spin_lock(&template_list
);
211 for (i
= 0; i
< ARRAY_SIZE(builtin_templates
); i
++) {
212 list_add_tail_rcu(&builtin_templates
[i
].list
,
215 spin_unlock(&template_list
);
218 struct ima_template_desc
*ima_template_desc_current(void)
221 ima_init_template_list();
223 lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE
);
228 int __init
ima_init_template(void)
230 struct ima_template_desc
*template = ima_template_desc_current();
233 result
= template_desc_init_fields(template->fmt
,
235 &(template->num_fields
));
237 pr_err("template %s init failed, result: %d\n",
238 (strlen(template->name
) ?
239 template->name
: template->fmt
), result
);
244 static struct ima_template_desc
*restore_template_fmt(char *template_name
)
246 struct ima_template_desc
*template_desc
= NULL
;
249 ret
= template_desc_init_fields(template_name
, NULL
, NULL
);
251 pr_err("attempting to initialize the template \"%s\" failed\n",
256 template_desc
= kzalloc(sizeof(*template_desc
), GFP_KERNEL
);
260 template_desc
->name
= "";
261 template_desc
->fmt
= kstrdup(template_name
, GFP_KERNEL
);
262 if (!template_desc
->fmt
)
265 spin_lock(&template_list
);
266 list_add_tail_rcu(&template_desc
->list
, &defined_templates
);
267 spin_unlock(&template_list
);
269 return template_desc
;
272 static int ima_restore_template_data(struct ima_template_desc
*template_desc
,
274 int template_data_size
,
275 struct ima_template_entry
**entry
)
277 struct binary_field_data
{
282 struct binary_field_data
*field_data
;
287 *entry
= kzalloc(sizeof(**entry
) +
288 template_desc
->num_fields
* sizeof(struct ima_field_data
),
293 (*entry
)->template_desc
= template_desc
;
294 for (i
= 0; i
< template_desc
->num_fields
; i
++) {
295 field_data
= template_data
+ offset
;
297 /* Each field of the template data is prefixed with a length. */
298 if (offset
> (template_data_size
- sizeof(*field_data
))) {
299 pr_err("Restoring the template field failed\n");
303 offset
+= sizeof(*field_data
);
305 if (ima_canonical_fmt
)
306 field_data
->len
= le32_to_cpu(field_data
->len
);
308 if (offset
> (template_data_size
- field_data
->len
)) {
309 pr_err("Restoring the template field data failed\n");
313 offset
+= field_data
->len
;
315 (*entry
)->template_data
[i
].len
= field_data
->len
;
316 (*entry
)->template_data_len
+= sizeof(field_data
->len
);
318 (*entry
)->template_data
[i
].data
=
319 kzalloc(field_data
->len
+ 1, GFP_KERNEL
);
320 if (!(*entry
)->template_data
[i
].data
) {
324 memcpy((*entry
)->template_data
[i
].data
, field_data
->data
,
326 (*entry
)->template_data_len
+= field_data
->len
;
330 ima_free_template_entry(*entry
);
337 /* Restore the serialized binary measurement list without extending PCRs. */
338 int ima_restore_measurement_list(loff_t size
, void *buf
)
340 struct binary_hdr_v1
{
342 u8 digest
[TPM_DIGEST_SIZE
];
343 u32 template_name_len
;
344 char template_name
[0];
346 char template_name
[MAX_TEMPLATE_NAME_LEN
];
348 struct binary_data_v1
{
349 u32 template_data_size
;
350 char template_data
[0];
353 struct ima_kexec_hdr
*khdr
= buf
;
354 struct binary_hdr_v1
*hdr_v1
;
355 struct binary_data_v1
*data_v1
;
357 void *bufp
= buf
+ sizeof(*khdr
);
359 struct ima_template_entry
*entry
;
360 struct ima_template_desc
*template_desc
;
361 unsigned long count
= 0;
364 if (!buf
|| size
< sizeof(*khdr
))
367 if (ima_canonical_fmt
) {
368 khdr
->version
= le16_to_cpu(khdr
->version
);
369 khdr
->count
= le64_to_cpu(khdr
->count
);
370 khdr
->buffer_size
= le64_to_cpu(khdr
->buffer_size
);
373 if (khdr
->version
!= 1) {
374 pr_err("attempting to restore a incompatible measurement list");
378 if (khdr
->count
> ULONG_MAX
- 1) {
379 pr_err("attempting to restore too many measurements");
384 * ima kexec buffer prefix: version, buffer size, count
385 * v1 format: pcr, digest, template-name-len, template-name,
386 * template-data-size, template-data
388 bufendp
= buf
+ khdr
->buffer_size
;
389 while ((bufp
< bufendp
) && (count
++ < khdr
->count
)) {
391 if (bufp
> (bufendp
- sizeof(*hdr_v1
))) {
392 pr_err("attempting to restore partial measurement\n");
396 bufp
+= sizeof(*hdr_v1
);
398 if (ima_canonical_fmt
)
399 hdr_v1
->template_name_len
=
400 le32_to_cpu(hdr_v1
->template_name_len
);
402 if ((hdr_v1
->template_name_len
>= MAX_TEMPLATE_NAME_LEN
) ||
403 (bufp
> (bufendp
- hdr_v1
->template_name_len
))) {
404 pr_err("attempting to restore a template name \
405 that is too long\n");
409 data_v1
= bufp
+= (u_int8_t
)hdr_v1
->template_name_len
;
411 /* template name is not null terminated */
412 memcpy(template_name
, hdr_v1
->template_name
,
413 hdr_v1
->template_name_len
);
414 template_name
[hdr_v1
->template_name_len
] = 0;
416 if (strcmp(template_name
, "ima") == 0) {
417 pr_err("attempting to restore an unsupported \
418 template \"%s\" failed\n", template_name
);
423 template_desc
= lookup_template_desc(template_name
);
424 if (!template_desc
) {
425 template_desc
= restore_template_fmt(template_name
);
431 * Only the running system's template format is initialized
432 * on boot. As needed, initialize the other template formats.
434 ret
= template_desc_init_fields(template_desc
->fmt
,
435 &(template_desc
->fields
),
436 &(template_desc
->num_fields
));
438 pr_err("attempting to restore the template fmt \"%s\" \
439 failed\n", template_desc
->fmt
);
444 if (bufp
> (bufendp
- sizeof(data_v1
->template_data_size
))) {
445 pr_err("restoring the template data size failed\n");
449 bufp
+= (u_int8_t
) sizeof(data_v1
->template_data_size
);
451 if (ima_canonical_fmt
)
452 data_v1
->template_data_size
=
453 le32_to_cpu(data_v1
->template_data_size
);
455 if (bufp
> (bufendp
- data_v1
->template_data_size
)) {
456 pr_err("restoring the template data failed\n");
460 bufp
+= data_v1
->template_data_size
;
462 ret
= ima_restore_template_data(template_desc
,
463 data_v1
->template_data
,
464 data_v1
->template_data_size
,
469 memcpy(entry
->digest
, hdr_v1
->digest
, TPM_DIGEST_SIZE
);
471 !ima_canonical_fmt
? hdr_v1
->pcr
: le32_to_cpu(hdr_v1
->pcr
);
472 ret
= ima_restore_measurement_entry(entry
);