Commit 989dc725 authored by Mimi Zohar's avatar Mimi Zohar

ima: define a new template field named 'd-ngv2' and templates

In preparation to differentiate between unsigned regular IMA file
hashes and fs-verity's file digests in the IMA measurement list,
define a new template field named 'd-ngv2'.

Also define two new templates named 'ima-ngv2' and 'ima-sigv2', which
include the new 'd-ngv2' field.
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 246d9216
...@@ -1903,7 +1903,8 @@ ...@@ -1903,7 +1903,8 @@
ima_template= [IMA] ima_template= [IMA]
Select one of defined IMA measurements template formats. Select one of defined IMA measurements template formats.
Formats: { "ima" | "ima-ng" | "ima-sig" } Formats: { "ima" | "ima-ng" | "ima-ngv2" | "ima-sig" |
"ima-sigv2" }
Default: "ima-ng" Default: "ima-ng"
ima_template_fmt= ima_template_fmt=
......
...@@ -67,6 +67,8 @@ descriptors by adding their identifier to the format string ...@@ -67,6 +67,8 @@ descriptors by adding their identifier to the format string
- 'n': the name of the event (i.e. the file name), with size up to 255 bytes; - 'n': the name of the event (i.e. the file name), with size up to 255 bytes;
- 'd-ng': the digest of the event, calculated with an arbitrary hash - 'd-ng': the digest of the event, calculated with an arbitrary hash
algorithm (field format: <hash algo>:digest); algorithm (field format: <hash algo>:digest);
- 'd-ngv2': same as d-ng, but prefixed with the "ima" digest type
(field format: <digest type>:<hash algo>:digest);
- 'd-modsig': the digest of the event without the appended modsig; - 'd-modsig': the digest of the event without the appended modsig;
- 'n-ng': the name of the event, without size limitations; - 'n-ng': the name of the event, without size limitations;
- 'sig': the file signature, or the EVM portable signature if the file - 'sig': the file signature, or the EVM portable signature if the file
...@@ -87,7 +89,9 @@ Below, there is the list of defined template descriptors: ...@@ -87,7 +89,9 @@ Below, there is the list of defined template descriptors:
- "ima": its format is ``d|n``; - "ima": its format is ``d|n``;
- "ima-ng" (default): its format is ``d-ng|n-ng``; - "ima-ng" (default): its format is ``d-ng|n-ng``;
- "ima-ngv2": its format is ``d-ngv2|n-ng``;
- "ima-sig": its format is ``d-ng|n-ng|sig``; - "ima-sig": its format is ``d-ng|n-ng|sig``;
- "ima-sigv2": its format is ``d-ngv2|n-ng|sig``;
- "ima-buf": its format is ``d-ng|n-ng|buf``; - "ima-buf": its format is ``d-ng|n-ng|buf``;
- "ima-modsig": its format is ``d-ng|n-ng|sig|d-modsig|modsig``; - "ima-modsig": its format is ``d-ng|n-ng|sig|d-modsig|modsig``;
- "evm-sig": its format is ``d-ng|n-ng|evmsig|xattrnames|xattrlengths|xattrvalues|iuid|igid|imode``; - "evm-sig": its format is ``d-ng|n-ng|evmsig|xattrnames|xattrlengths|xattrvalues|iuid|igid|imode``;
......
...@@ -20,6 +20,8 @@ static struct ima_template_desc builtin_templates[] = { ...@@ -20,6 +20,8 @@ static struct ima_template_desc builtin_templates[] = {
{.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
{.name = "ima-ng", .fmt = "d-ng|n-ng"}, {.name = "ima-ng", .fmt = "d-ng|n-ng"},
{.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"},
{.name = "ima-ngv2", .fmt = "d-ngv2|n-ng"},
{.name = "ima-sigv2", .fmt = "d-ngv2|n-ng|sig"},
{.name = "ima-buf", .fmt = "d-ng|n-ng|buf"}, {.name = "ima-buf", .fmt = "d-ng|n-ng|buf"},
{.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"}, {.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"},
{.name = "evm-sig", {.name = "evm-sig",
...@@ -38,6 +40,8 @@ static const struct ima_template_field supported_fields[] = { ...@@ -38,6 +40,8 @@ static const struct ima_template_field supported_fields[] = {
.field_show = ima_show_template_string}, .field_show = ima_show_template_string},
{.field_id = "d-ng", .field_init = ima_eventdigest_ng_init, {.field_id = "d-ng", .field_init = ima_eventdigest_ng_init,
.field_show = ima_show_template_digest_ng}, .field_show = ima_show_template_digest_ng},
{.field_id = "d-ngv2", .field_init = ima_eventdigest_ngv2_init,
.field_show = ima_show_template_digest_ngv2},
{.field_id = "n-ng", .field_init = ima_eventname_ng_init, {.field_id = "n-ng", .field_init = ima_eventname_ng_init,
.field_show = ima_show_template_string}, .field_show = ima_show_template_string},
{.field_id = "sig", .field_init = ima_eventsig_init, {.field_id = "sig", .field_init = ima_eventsig_init,
......
...@@ -24,11 +24,22 @@ static bool ima_template_hash_algo_allowed(u8 algo) ...@@ -24,11 +24,22 @@ static bool ima_template_hash_algo_allowed(u8 algo)
enum data_formats { enum data_formats {
DATA_FMT_DIGEST = 0, DATA_FMT_DIGEST = 0,
DATA_FMT_DIGEST_WITH_ALGO, DATA_FMT_DIGEST_WITH_ALGO,
DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO,
DATA_FMT_STRING, DATA_FMT_STRING,
DATA_FMT_HEX, DATA_FMT_HEX,
DATA_FMT_UINT DATA_FMT_UINT
}; };
enum digest_type {
DIGEST_TYPE_IMA,
DIGEST_TYPE__LAST
};
#define DIGEST_TYPE_NAME_LEN_MAX 4 /* including NUL */
static const char * const digest_type_name[DIGEST_TYPE__LAST] = {
[DIGEST_TYPE_IMA] = "ima"
};
static int ima_write_template_field_data(const void *data, const u32 datalen, static int ima_write_template_field_data(const void *data, const u32 datalen,
enum data_formats datafmt, enum data_formats datafmt,
struct ima_field_data *field_data) struct ima_field_data *field_data)
...@@ -72,8 +83,9 @@ static void ima_show_template_data_ascii(struct seq_file *m, ...@@ -72,8 +83,9 @@ static void ima_show_template_data_ascii(struct seq_file *m,
u32 buflen = field_data->len; u32 buflen = field_data->len;
switch (datafmt) { switch (datafmt) {
case DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO:
case DATA_FMT_DIGEST_WITH_ALGO: case DATA_FMT_DIGEST_WITH_ALGO:
buf_ptr = strnchr(field_data->data, buflen, ':'); buf_ptr = strrchr(field_data->data, ':');
if (buf_ptr != field_data->data) if (buf_ptr != field_data->data)
seq_printf(m, "%s", field_data->data); seq_printf(m, "%s", field_data->data);
...@@ -178,6 +190,14 @@ void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show, ...@@ -178,6 +190,14 @@ void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
field_data); field_data);
} }
void ima_show_template_digest_ngv2(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data)
{
ima_show_template_field_data(m, show,
DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO,
field_data);
}
void ima_show_template_string(struct seq_file *m, enum ima_show_type show, void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
...@@ -265,28 +285,35 @@ int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp, ...@@ -265,28 +285,35 @@ int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
} }
static int ima_eventdigest_init_common(const u8 *digest, u32 digestsize, static int ima_eventdigest_init_common(const u8 *digest, u32 digestsize,
u8 hash_algo, u8 digest_type, u8 hash_algo,
struct ima_field_data *field_data) struct ima_field_data *field_data)
{ {
/* /*
* digest formats: * digest formats:
* - DATA_FMT_DIGEST: digest * - DATA_FMT_DIGEST: digest
* - DATA_FMT_DIGEST_WITH_ALGO: <hash algo> + ':' + '\0' + digest, * - DATA_FMT_DIGEST_WITH_ALGO: <hash algo> + ':' + '\0' + digest,
* - DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO:
* <digest type> + ':' + <hash algo> + ':' + '\0' + digest,
* *
* where 'DATA_FMT_DIGEST' is the original digest format ('d') * where 'DATA_FMT_DIGEST' is the original digest format ('d')
* with a hash size limitation of 20 bytes, * with a hash size limitation of 20 bytes,
* where <digest type> is "ima",
* where <hash algo> is the hash_algo_name[] string. * where <hash algo> is the hash_algo_name[] string.
*/ */
u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 }; u8 buffer[DIGEST_TYPE_NAME_LEN_MAX + CRYPTO_MAX_ALG_NAME + 2 +
IMA_MAX_DIGEST_SIZE] = { 0 };
enum data_formats fmt = DATA_FMT_DIGEST; enum data_formats fmt = DATA_FMT_DIGEST;
u32 offset = 0; u32 offset = 0;
if (hash_algo < HASH_ALGO__LAST) { if (digest_type < DIGEST_TYPE__LAST && hash_algo < HASH_ALGO__LAST) {
fmt = DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO;
offset += 1 + sprintf(buffer, "%s:%s:",
digest_type_name[digest_type],
hash_algo_name[hash_algo]);
} else if (hash_algo < HASH_ALGO__LAST) {
fmt = DATA_FMT_DIGEST_WITH_ALGO; fmt = DATA_FMT_DIGEST_WITH_ALGO;
offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s", offset += 1 + sprintf(buffer, "%s:",
hash_algo_name[hash_algo]); hash_algo_name[hash_algo]);
buffer[offset] = ':';
offset += 2;
} }
if (digest) if (digest)
...@@ -361,7 +388,8 @@ int ima_eventdigest_init(struct ima_event_data *event_data, ...@@ -361,7 +388,8 @@ int ima_eventdigest_init(struct ima_event_data *event_data,
cur_digestsize = hash.hdr.length; cur_digestsize = hash.hdr.length;
out: out:
return ima_eventdigest_init_common(cur_digest, cur_digestsize, return ima_eventdigest_init_common(cur_digest, cur_digestsize,
HASH_ALGO__LAST, field_data); DIGEST_TYPE__LAST, HASH_ALGO__LAST,
field_data);
} }
/* /*
...@@ -382,7 +410,32 @@ int ima_eventdigest_ng_init(struct ima_event_data *event_data, ...@@ -382,7 +410,32 @@ int ima_eventdigest_ng_init(struct ima_event_data *event_data,
hash_algo = event_data->iint->ima_hash->algo; hash_algo = event_data->iint->ima_hash->algo;
out: out:
return ima_eventdigest_init_common(cur_digest, cur_digestsize, return ima_eventdigest_init_common(cur_digest, cur_digestsize,
hash_algo, field_data); DIGEST_TYPE__LAST, hash_algo,
field_data);
}
/*
* This function writes the digest of an event (without size limit),
* prefixed with both the digest type and hash algorithm.
*/
int ima_eventdigest_ngv2_init(struct ima_event_data *event_data,
struct ima_field_data *field_data)
{
u8 *cur_digest = NULL, hash_algo = ima_hash_algo;
u32 cur_digestsize = 0;
u8 digest_type = DIGEST_TYPE_IMA;
if (event_data->violation) /* recording a violation. */
goto out;
cur_digest = event_data->iint->ima_hash->digest;
cur_digestsize = event_data->iint->ima_hash->length;
hash_algo = event_data->iint->ima_hash->algo;
out:
return ima_eventdigest_init_common(cur_digest, cur_digestsize,
digest_type, hash_algo,
field_data);
} }
/* /*
...@@ -417,7 +470,8 @@ int ima_eventdigest_modsig_init(struct ima_event_data *event_data, ...@@ -417,7 +470,8 @@ int ima_eventdigest_modsig_init(struct ima_event_data *event_data,
} }
return ima_eventdigest_init_common(cur_digest, cur_digestsize, return ima_eventdigest_init_common(cur_digest, cur_digestsize,
hash_algo, field_data); DIGEST_TYPE__LAST, hash_algo,
field_data);
} }
static int ima_eventname_init_common(struct ima_event_data *event_data, static int ima_eventname_init_common(struct ima_event_data *event_data,
......
...@@ -21,6 +21,8 @@ void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, ...@@ -21,6 +21,8 @@ void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show, void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
void ima_show_template_digest_ngv2(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data);
void ima_show_template_string(struct seq_file *m, enum ima_show_type show, void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
struct ima_field_data *field_data); struct ima_field_data *field_data);
void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
...@@ -38,6 +40,8 @@ int ima_eventname_init(struct ima_event_data *event_data, ...@@ -38,6 +40,8 @@ int ima_eventname_init(struct ima_event_data *event_data,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventdigest_ng_init(struct ima_event_data *event_data, int ima_eventdigest_ng_init(struct ima_event_data *event_data,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventdigest_ngv2_init(struct ima_event_data *event_data,
struct ima_field_data *field_data);
int ima_eventdigest_modsig_init(struct ima_event_data *event_data, int ima_eventdigest_modsig_init(struct ima_event_data *event_data,
struct ima_field_data *field_data); struct ima_field_data *field_data);
int ima_eventname_ng_init(struct ima_event_data *event_data, int ima_eventname_ng_init(struct ima_event_data *event_data,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment