1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 Politecnico di Torino, Italy
4 * TORSEC group -- https://security.polito.it
6 * Author: Roberto Sassu <roberto.sassu@polito.it>
9 * Helpers to manage template descriptors.
12 #include <linux/rculist.h>
14 #include "ima_template_lib.h"
16 enum header_fields
{ HDR_PCR
, HDR_DIGEST
, HDR_TEMPLATE_NAME
,
17 HDR_TEMPLATE_DATA
, HDR__LAST
};
19 static struct ima_template_desc builtin_templates
[] = {
20 {.name
= IMA_TEMPLATE_IMA_NAME
, .fmt
= IMA_TEMPLATE_IMA_FMT
},
21 {.name
= "ima-ng", .fmt
= "d-ng|n-ng"},
22 {.name
= "ima-sig", .fmt
= "d-ng|n-ng|sig"},
23 {.name
= "ima-buf", .fmt
= "d-ng|n-ng|buf"},
24 {.name
= "ima-modsig", .fmt
= "d-ng|n-ng|sig|d-modsig|modsig"},
25 {.name
= "", .fmt
= ""}, /* placeholder for a custom format */
28 static LIST_HEAD(defined_templates
);
29 static DEFINE_SPINLOCK(template_list
);
31 static const struct ima_template_field supported_fields
[] = {
32 {.field_id
= "d", .field_init
= ima_eventdigest_init
,
33 .field_show
= ima_show_template_digest
},
34 {.field_id
= "n", .field_init
= ima_eventname_init
,
35 .field_show
= ima_show_template_string
},
36 {.field_id
= "d-ng", .field_init
= ima_eventdigest_ng_init
,
37 .field_show
= ima_show_template_digest_ng
},
38 {.field_id
= "n-ng", .field_init
= ima_eventname_ng_init
,
39 .field_show
= ima_show_template_string
},
40 {.field_id
= "sig", .field_init
= ima_eventsig_init
,
41 .field_show
= ima_show_template_sig
},
42 {.field_id
= "buf", .field_init
= ima_eventbuf_init
,
43 .field_show
= ima_show_template_buf
},
44 {.field_id
= "d-modsig", .field_init
= ima_eventdigest_modsig_init
,
45 .field_show
= ima_show_template_digest_ng
},
46 {.field_id
= "modsig", .field_init
= ima_eventmodsig_init
,
47 .field_show
= ima_show_template_sig
},
51 * Used when restoring measurements carried over from a kexec. 'd' and 'n' don't
52 * need to be accounted for since they shouldn't be defined in the same template
53 * description as 'd-ng' and 'n-ng' respectively.
55 #define MAX_TEMPLATE_NAME_LEN sizeof("d-ng|n-ng|sig|buf|d-modisg|modsig")
57 static struct ima_template_desc
*ima_template
;
58 static struct ima_template_desc
*ima_buf_template
;
61 * ima_template_has_modsig - Check whether template has modsig-related fields.
62 * @ima_template: IMA template to check.
64 * Tells whether the given template has fields referencing a file's appended
67 bool ima_template_has_modsig(const struct ima_template_desc
*ima_template
)
71 for (i
= 0; i
< ima_template
->num_fields
; i
++)
72 if (!strcmp(ima_template
->fields
[i
]->field_id
, "modsig") ||
73 !strcmp(ima_template
->fields
[i
]->field_id
, "d-modsig"))
79 static int __init
ima_template_setup(char *str
)
81 struct ima_template_desc
*template_desc
;
82 int template_len
= strlen(str
);
87 ima_init_template_list();
90 * Verify that a template with the supplied name exists.
91 * If not, use CONFIG_IMA_DEFAULT_TEMPLATE.
93 template_desc
= lookup_template_desc(str
);
95 pr_err("template %s not found, using %s\n",
96 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
101 * Verify whether the current hash algorithm is supported
102 * by the 'ima' template.
104 if (template_len
== 3 && strcmp(str
, IMA_TEMPLATE_IMA_NAME
) == 0 &&
105 ima_hash_algo
!= HASH_ALGO_SHA1
&& ima_hash_algo
!= HASH_ALGO_MD5
) {
106 pr_err("template does not support hash alg\n");
110 ima_template
= template_desc
;
113 __setup("ima_template=", ima_template_setup
);
115 static int __init
ima_template_fmt_setup(char *str
)
117 int num_templates
= ARRAY_SIZE(builtin_templates
);
122 if (template_desc_init_fields(str
, NULL
, NULL
) < 0) {
123 pr_err("format string '%s' not valid, using template %s\n",
124 str
, CONFIG_IMA_DEFAULT_TEMPLATE
);
128 builtin_templates
[num_templates
- 1].fmt
= str
;
129 ima_template
= builtin_templates
+ num_templates
- 1;
133 __setup("ima_template_fmt=", ima_template_fmt_setup
);
135 struct ima_template_desc
*lookup_template_desc(const char *name
)
137 struct ima_template_desc
*template_desc
;
141 list_for_each_entry_rcu(template_desc
, &defined_templates
, list
) {
142 if ((strcmp(template_desc
->name
, name
) == 0) ||
143 (strcmp(template_desc
->fmt
, name
) == 0)) {
149 return found
? template_desc
: NULL
;
152 static const struct ima_template_field
*
153 lookup_template_field(const char *field_id
)
157 for (i
= 0; i
< ARRAY_SIZE(supported_fields
); i
++)
158 if (strncmp(supported_fields
[i
].field_id
, field_id
,
159 IMA_TEMPLATE_FIELD_ID_MAX_LEN
) == 0)
160 return &supported_fields
[i
];
164 static int template_fmt_size(const char *template_fmt
)
167 int template_fmt_len
= strlen(template_fmt
);
170 while (i
< template_fmt_len
) {
180 int template_desc_init_fields(const char *template_fmt
,
181 const struct ima_template_field
***fields
,
184 const char *template_fmt_ptr
;
185 const struct ima_template_field
*found_fields
[IMA_TEMPLATE_NUM_FIELDS_MAX
];
186 int template_num_fields
;
189 if (num_fields
&& *num_fields
> 0) /* already initialized? */
192 template_num_fields
= template_fmt_size(template_fmt
);
194 if (template_num_fields
> IMA_TEMPLATE_NUM_FIELDS_MAX
) {
195 pr_err("format string '%s' contains too many fields\n",
200 for (i
= 0, template_fmt_ptr
= template_fmt
; i
< template_num_fields
;
201 i
++, template_fmt_ptr
+= len
+ 1) {
202 char tmp_field_id
[IMA_TEMPLATE_FIELD_ID_MAX_LEN
+ 1];
204 len
= strchrnul(template_fmt_ptr
, '|') - template_fmt_ptr
;
205 if (len
== 0 || len
> IMA_TEMPLATE_FIELD_ID_MAX_LEN
) {
206 pr_err("Invalid field with length %d\n", len
);
210 memcpy(tmp_field_id
, template_fmt_ptr
, len
);
211 tmp_field_id
[len
] = '\0';
212 found_fields
[i
] = lookup_template_field(tmp_field_id
);
213 if (!found_fields
[i
]) {
214 pr_err("field '%s' not found\n", tmp_field_id
);
219 if (fields
&& num_fields
) {
220 *fields
= kmalloc_array(i
, sizeof(*fields
), GFP_KERNEL
);
224 memcpy(*fields
, found_fields
, i
* sizeof(*fields
));
231 void ima_init_template_list(void)
235 if (!list_empty(&defined_templates
))
238 spin_lock(&template_list
);
239 for (i
= 0; i
< ARRAY_SIZE(builtin_templates
); i
++) {
240 list_add_tail_rcu(&builtin_templates
[i
].list
,
243 spin_unlock(&template_list
);
246 struct ima_template_desc
*ima_template_desc_current(void)
249 ima_init_template_list();
251 lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE
);
256 struct ima_template_desc
*ima_template_desc_buf(void)
258 if (!ima_buf_template
) {
259 ima_init_template_list();
260 ima_buf_template
= lookup_template_desc("ima-buf");
262 return ima_buf_template
;
265 int __init
ima_init_template(void)
267 struct ima_template_desc
*template = ima_template_desc_current();
270 result
= template_desc_init_fields(template->fmt
,
272 &(template->num_fields
));
274 pr_err("template %s init failed, result: %d\n",
275 (strlen(template->name
) ?
276 template->name
: template->fmt
), result
);
280 template = ima_template_desc_buf();
282 pr_err("Failed to get ima-buf template\n");
286 result
= template_desc_init_fields(template->fmt
,
288 &(template->num_fields
));
290 pr_err("template %s init failed, result: %d\n",
291 (strlen(template->name
) ?
292 template->name
: template->fmt
), result
);
297 static struct ima_template_desc
*restore_template_fmt(char *template_name
)
299 struct ima_template_desc
*template_desc
= NULL
;
302 ret
= template_desc_init_fields(template_name
, NULL
, NULL
);
304 pr_err("attempting to initialize the template \"%s\" failed\n",
309 template_desc
= kzalloc(sizeof(*template_desc
), GFP_KERNEL
);
313 template_desc
->name
= "";
314 template_desc
->fmt
= kstrdup(template_name
, GFP_KERNEL
);
315 if (!template_desc
->fmt
)
318 spin_lock(&template_list
);
319 list_add_tail_rcu(&template_desc
->list
, &defined_templates
);
320 spin_unlock(&template_list
);
322 return template_desc
;
325 static int ima_restore_template_data(struct ima_template_desc
*template_desc
,
327 int template_data_size
,
328 struct ima_template_entry
**entry
)
330 struct tpm_digest
*digests
;
334 *entry
= kzalloc(struct_size(*entry
, template_data
,
335 template_desc
->num_fields
), GFP_NOFS
);
339 digests
= kcalloc(NR_BANKS(ima_tpm_chip
) + ima_extra_slots
,
340 sizeof(*digests
), GFP_NOFS
);
346 (*entry
)->digests
= digests
;
348 ret
= ima_parse_buf(template_data
, template_data
+ template_data_size
,
349 NULL
, template_desc
->num_fields
,
350 (*entry
)->template_data
, NULL
, NULL
,
351 ENFORCE_FIELDS
| ENFORCE_BUFEND
, "template data");
353 kfree((*entry
)->digests
);
358 (*entry
)->template_desc
= template_desc
;
359 for (i
= 0; i
< template_desc
->num_fields
; i
++) {
360 struct ima_field_data
*field_data
= &(*entry
)->template_data
[i
];
361 u8
*data
= field_data
->data
;
363 (*entry
)->template_data
[i
].data
=
364 kzalloc(field_data
->len
+ 1, GFP_KERNEL
);
365 if (!(*entry
)->template_data
[i
].data
) {
369 memcpy((*entry
)->template_data
[i
].data
, data
, field_data
->len
);
370 (*entry
)->template_data_len
+= sizeof(field_data
->len
);
371 (*entry
)->template_data_len
+= field_data
->len
;
375 ima_free_template_entry(*entry
);
382 /* Restore the serialized binary measurement list without extending PCRs. */
383 int ima_restore_measurement_list(loff_t size
, void *buf
)
385 char template_name
[MAX_TEMPLATE_NAME_LEN
];
386 unsigned char zero
[TPM_DIGEST_SIZE
] = { 0 };
388 struct ima_kexec_hdr
*khdr
= buf
;
389 struct ima_field_data hdr
[HDR__LAST
] = {
390 [HDR_PCR
] = {.len
= sizeof(u32
)},
391 [HDR_DIGEST
] = {.len
= TPM_DIGEST_SIZE
},
394 void *bufp
= buf
+ sizeof(*khdr
);
396 struct ima_template_entry
*entry
;
397 struct ima_template_desc
*template_desc
;
398 DECLARE_BITMAP(hdr_mask
, HDR__LAST
);
399 unsigned long count
= 0;
402 if (!buf
|| size
< sizeof(*khdr
))
405 if (ima_canonical_fmt
) {
406 khdr
->version
= le16_to_cpu(khdr
->version
);
407 khdr
->count
= le64_to_cpu(khdr
->count
);
408 khdr
->buffer_size
= le64_to_cpu(khdr
->buffer_size
);
411 if (khdr
->version
!= 1) {
412 pr_err("attempting to restore a incompatible measurement list");
416 if (khdr
->count
> ULONG_MAX
- 1) {
417 pr_err("attempting to restore too many measurements");
421 bitmap_zero(hdr_mask
, HDR__LAST
);
422 bitmap_set(hdr_mask
, HDR_PCR
, 1);
423 bitmap_set(hdr_mask
, HDR_DIGEST
, 1);
426 * ima kexec buffer prefix: version, buffer size, count
427 * v1 format: pcr, digest, template-name-len, template-name,
428 * template-data-size, template-data
430 bufendp
= buf
+ khdr
->buffer_size
;
431 while ((bufp
< bufendp
) && (count
++ < khdr
->count
)) {
432 int enforce_mask
= ENFORCE_FIELDS
;
434 enforce_mask
|= (count
== khdr
->count
) ? ENFORCE_BUFEND
: 0;
435 ret
= ima_parse_buf(bufp
, bufendp
, &bufp
, HDR__LAST
, hdr
, NULL
,
436 hdr_mask
, enforce_mask
, "entry header");
440 if (hdr
[HDR_TEMPLATE_NAME
].len
>= MAX_TEMPLATE_NAME_LEN
) {
441 pr_err("attempting to restore a template name that is too long\n");
446 /* template name is not null terminated */
447 memcpy(template_name
, hdr
[HDR_TEMPLATE_NAME
].data
,
448 hdr
[HDR_TEMPLATE_NAME
].len
);
449 template_name
[hdr
[HDR_TEMPLATE_NAME
].len
] = 0;
451 if (strcmp(template_name
, "ima") == 0) {
452 pr_err("attempting to restore an unsupported template \"%s\" failed\n",
458 template_desc
= lookup_template_desc(template_name
);
459 if (!template_desc
) {
460 template_desc
= restore_template_fmt(template_name
);
466 * Only the running system's template format is initialized
467 * on boot. As needed, initialize the other template formats.
469 ret
= template_desc_init_fields(template_desc
->fmt
,
470 &(template_desc
->fields
),
471 &(template_desc
->num_fields
));
473 pr_err("attempting to restore the template fmt \"%s\" failed\n",
479 ret
= ima_restore_template_data(template_desc
,
480 hdr
[HDR_TEMPLATE_DATA
].data
,
481 hdr
[HDR_TEMPLATE_DATA
].len
,
486 if (memcmp(hdr
[HDR_DIGEST
].data
, zero
, sizeof(zero
))) {
487 ret
= ima_calc_field_array_hash(
488 &entry
->template_data
[0],
491 pr_err("cannot calculate template digest\n");
497 entry
->pcr
= !ima_canonical_fmt
? *(hdr
[HDR_PCR
].data
) :
498 le32_to_cpu(*(hdr
[HDR_PCR
].data
));
499 ret
= ima_restore_measurement_entry(entry
);