// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013 Politecnico di Torino, Italy
 *                    TORSEC group -- https://security.polito.it
 *
 * Author: Roberto Sassu <roberto.sassu@polito.it>
 *
 * File: ima_template_lib.c
 *      Library of supported template fields.
 */

#include "ima_template_lib.h"
#include <linux/xattr.h>
#include <linux/evm.h>

static bool ima_template_hash_algo_allowed(u8 algo)
{
	if (algo == HASH_ALGO_SHA1 || algo == HASH_ALGO_MD5)
		return true;

	return false;
}

enum data_formats {
	DATA_FMT_DIGEST = 0,
	DATA_FMT_DIGEST_WITH_ALGO,
	DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO,
	DATA_FMT_STRING,
	DATA_FMT_HEX,
	DATA_FMT_UINT
};

enum digest_type {
	DIGEST_TYPE_IMA,
	DIGEST_TYPE_VERITY,
	DIGEST_TYPE__LAST
};

#define DIGEST_TYPE_NAME_LEN_MAX 7	/* including NUL */
static const char * const digest_type_name[DIGEST_TYPE__LAST] = {
	[DIGEST_TYPE_IMA] = "ima",
	[DIGEST_TYPE_VERITY] = "verity"
};

static int ima_write_template_field_data(const void *data, const u32 datalen,
					 enum data_formats datafmt,
					 struct ima_field_data *field_data)
{
	u8 *buf, *buf_ptr;
	u32 buflen = datalen;

	if (datafmt == DATA_FMT_STRING)
		buflen = datalen + 1;

	buf = kzalloc(buflen, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	memcpy(buf, data, datalen);

	/*
	 * Replace all space characters with underscore for event names and
	 * strings. This avoid that, during the parsing of a measurements list,
	 * filenames with spaces or that end with the suffix ' (deleted)' are
	 * split into multiple template fields (the space is the delimitator
	 * character for measurements lists in ASCII format).
	 */
	if (datafmt == DATA_FMT_STRING) {
		for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
			if (*buf_ptr == ' ')
				*buf_ptr = '_';
	}

	field_data->data = buf;
	field_data->len = buflen;
	return 0;
}

static void ima_show_template_data_ascii(struct seq_file *m,
					 enum ima_show_type show,
					 enum data_formats datafmt,
					 struct ima_field_data *field_data)
{
	u8 *buf_ptr = field_data->data;
	u32 buflen = field_data->len;

	switch (datafmt) {
	case DATA_FMT_DIGEST_WITH_TYPE_AND_ALGO:
	case DATA_FMT_DIGEST_WITH_ALGO:
		buf_ptr = strrchr(field_data->data, ':');
		if (buf_ptr != field_data->data)
			seq_printf(m, "%s", field_data->data);

		/* skip ':' and '\0' */
		buf_ptr += 2;
		buflen -= buf_ptr - field_data->data;
		fallthrough;
	case DATA_FMT_DIGEST:
	case DATA_FMT_HEX:
		if (!buflen)
			break;
		ima_print_digest(m, buf_ptr, buflen);
		break;
	case DATA_FMT_STRING:
		seq_printf(m, "%s", buf_ptr);
		break;
	case DATA_FMT_UINT:
		switch (field_data->len) {
		case sizeof(u8):
			seq_printf(m, "%u", *(u8 *)buf_ptr);
			break;
		case sizeof(u16):
			if (ima_canonical_fmt)
				seq_printf(m, "%u",
					   le16_to_cpu(*(__le16 *)buf_ptr));
			else
				seq_printf(m, "%u", *(u16 *)buf_ptr);
			break;
		case sizeof(u32):
			if (ima_canonical_fmt)
				seq_printf(m, "%u",
					   le32_to_cpu(*(__le32 *)buf_ptr));
			else
				seq_printf(m, "%u", *(u32 *)buf_ptr);
			break;
		case sizeof(u64):
			if (ima_canonical_fmt)
				seq_printf(m, "%llu",
					   le64_to_cpu(*(__le64 *)buf_ptr));
			else
				seq_printf(m, "%llu", *(u64 *)buf_ptr);
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
}

static void ima_show_template_data_binary(struct seq_file *m,
					  enum ima_show_type show,
					  enum data_formats datafmt,
					  struct ima_field_data *field_data)
{
	u32 len = (show == IMA_SHOW_BINARY_OLD_STRING_FMT) ?
	    strlen(field_data->data) : field_data->len;

	if (show != IMA_SHOW_BINARY_NO_FIELD_LEN) {
		u32 field_len = !ima_canonical_fmt ?
				len : (__force u32)cpu_to_le32(len);

		ima_putc(m, &field_len, sizeof(field_len));
	}

	if (!len)
		return;

	ima_putc(m, field_data->data, len);
}

static void ima_show_template_field_data(struct seq_file *m,
					 enum ima_show_type show,
					 enum data_formats datafmt,
					 struct ima_field_data *field_data)
{
	switch (show) {
	case IMA_SHOW_ASCII:
		ima_show_template_data_ascii(m, show, datafmt, field_data);
		break;
	case IMA_SHOW_BINARY:
	case IMA_SHOW_BINARY_NO_FIELD_LEN:
	case IMA_SHOW_BINARY_OLD_STRING_FMT:
		ima_show_template_data_binary(m, show, datafmt, field_data);
		break;
	default:
		break;
	}
}

void ima_show_template_digest(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, field_data);
}

void ima_show_template_digest_ng(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_ALGO,
				     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,
			      struct ima_field_data *field_data)
{
	ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
}

void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
			   struct ima_field_data *field_data)
{
	ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
}

void ima_show_template_buf(struct seq_file *m, enum ima_show_type show,
			   struct ima_field_data *field_data)
{
	ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
}

void ima_show_template_uint(struct seq_file *m, enum ima_show_type show,
			    struct ima_field_data *field_data)
{
	ima_show_template_field_data(m, show, DATA_FMT_UINT, field_data);
}

/**
 * ima_parse_buf() - Parses lengths and data from an input buffer
 * @bufstartp:       Buffer start address.
 * @bufendp:         Buffer end address.
 * @bufcurp:         Pointer to remaining (non-parsed) data.
 * @maxfields:       Length of fields array.
 * @fields:          Array containing lengths and pointers of parsed data.
 * @curfields:       Number of array items containing parsed data.
 * @len_mask:        Bitmap (if bit is set, data length should not be parsed).
 * @enforce_mask:    Check if curfields == maxfields and/or bufcurp == bufendp.
 * @bufname:         String identifier of the input buffer.
 *
 * Return: 0 on success, -EINVAL on error.
 */
int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
		  int maxfields, struct ima_field_data *fields, int *curfields,
		  unsigned long *len_mask, int enforce_mask, char *bufname)
{
	void *bufp = bufstartp;
	int i;

	for (i = 0; i < maxfields; i++) {
		if (len_mask == NULL || !test_bit(i, len_mask)) {
			if (bufp > (bufendp - sizeof(u32)))
				break;

			if (ima_canonical_fmt)
				fields[i].len = le32_to_cpu(*(__le32 *)bufp);
			else
				fields[i].len = *(u32 *)bufp;

			bufp += sizeof(u32);
		}

		if (bufp > (bufendp - fields[i].len))
			break;

		fields[i].data = bufp;
		bufp += fields[i].len;
	}

	if ((enforce_mask & ENFORCE_FIELDS) && i != maxfields) {
		pr_err("%s: nr of fields mismatch: expected: %d, current: %d\n",
		       bufname, maxfields, i);
		return -EINVAL;
	}

	if ((enforce_mask & ENFORCE_BUFEND) && bufp != bufendp) {
		pr_err("%s: buf end mismatch: expected: %p, current: %p\n",
		       bufname, bufendp, bufp);
		return -EINVAL;
	}

	if (curfields)
		*curfields = i;

	if (bufcurp)
		*bufcurp = bufp;

	return 0;
}

static int ima_eventdigest_init_common(const u8 *digest, u32 digestsize,
				       u8 digest_type, u8 hash_algo,
				       struct ima_field_data *field_data)
{
	/*
	 * digest formats:
	 *  - DATA_FMT_DIGEST: 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')
	 *      with a hash size limitation of 20 bytes,
	 *    where <digest type> is either "ima" or "verity",
	 *    where <hash algo> is the hash_algo_name[] string.
	 */
	u8 buffer[DIGEST_TYPE_NAME_LEN_MAX + CRYPTO_MAX_ALG_NAME + 2 +
		IMA_MAX_DIGEST_SIZE] = { 0 };
	enum data_formats fmt = DATA_FMT_DIGEST;
	u32 offset = 0;

	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;
		offset += 1 + sprintf(buffer, "%s:",
				      hash_algo_name[hash_algo]);
	}

	if (digest) {
		memcpy(buffer + offset, digest, digestsize);
	} else {
		/*
		 * If digest is NULL, the event being recorded is a violation.
		 * Make room for the digest by increasing the offset by the
		 * hash algorithm digest size. If the hash algorithm is not
		 * specified increase the offset by IMA_DIGEST_SIZE which
		 * fits SHA1 or MD5
		 */
		if (hash_algo < HASH_ALGO__LAST)
			offset += hash_digest_size[hash_algo];
		else
			offset += IMA_DIGEST_SIZE;
	}

	return ima_write_template_field_data(buffer, offset + digestsize,
					     fmt, field_data);
}

/*
 * This function writes the digest of an event (with size limit).
 */
int ima_eventdigest_init(struct ima_event_data *event_data,
			 struct ima_field_data *field_data)
{
	struct ima_max_digest_data hash;
	struct ima_digest_data *hash_hdr = container_of(&hash.hdr,
						struct ima_digest_data, hdr);
	u8 *cur_digest = NULL;
	u32 cur_digestsize = 0;
	struct inode *inode;
	int result;

	memset(&hash, 0, sizeof(hash));

	if (event_data->violation)	/* recording a violation. */
		goto out;

	if (ima_template_hash_algo_allowed(event_data->iint->ima_hash->algo)) {
		cur_digest = event_data->iint->ima_hash->digest;
		cur_digestsize = event_data->iint->ima_hash->length;
		goto out;
	}

	if ((const char *)event_data->filename == boot_aggregate_name) {
		if (ima_tpm_chip) {
			hash.hdr.algo = HASH_ALGO_SHA1;
			result = ima_calc_boot_aggregate(hash_hdr);

			/* algo can change depending on available PCR banks */
			if (!result && hash.hdr.algo != HASH_ALGO_SHA1)
				result = -EINVAL;

			if (result < 0)
				memset(&hash, 0, sizeof(hash));
		}

		cur_digest = hash_hdr->digest;
		cur_digestsize = hash_digest_size[HASH_ALGO_SHA1];
		goto out;
	}

	if (!event_data->file)	/* missing info to re-calculate the digest */
		return -EINVAL;

	inode = file_inode(event_data->file);
	hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
	    ima_hash_algo : HASH_ALGO_SHA1;
	result = ima_calc_file_hash(event_data->file, hash_hdr);
	if (result) {
		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
				    event_data->filename, "collect_data",
				    "failed", result, 0);
		return result;
	}
	cur_digest = hash_hdr->digest;
	cur_digestsize = hash.hdr.length;
out:
	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
					   DIGEST_TYPE__LAST, HASH_ALGO__LAST,
					   field_data);
}

/*
 * This function writes the digest of an event (without size limit).
 */
int ima_eventdigest_ng_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;

	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__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;
	if (event_data->iint->flags & IMA_VERITY_REQUIRED)
		digest_type = DIGEST_TYPE_VERITY;
out:
	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
					   digest_type, hash_algo,
					   field_data);
}

/*
 * This function writes the digest of the file which is expected to match the
 * digest contained in the file's appended signature.
 */
int ima_eventdigest_modsig_init(struct ima_event_data *event_data,
				struct ima_field_data *field_data)
{
	enum hash_algo hash_algo;
	const u8 *cur_digest;
	u32 cur_digestsize;

	if (!event_data->modsig)
		return 0;

	if (event_data->violation) {
		/* Recording a violation. */
		hash_algo = HASH_ALGO_SHA1;
		cur_digest = NULL;
		cur_digestsize = 0;
	} else {
		int rc;

		rc = ima_get_modsig_digest(event_data->modsig, &hash_algo,
					   &cur_digest, &cur_digestsize);
		if (rc)
			return rc;
		else if (hash_algo == HASH_ALGO__LAST || cur_digestsize == 0)
			/* There was some error collecting the digest. */
			return -EINVAL;
	}

	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
					   DIGEST_TYPE__LAST, hash_algo,
					   field_data);
}

static int ima_eventname_init_common(struct ima_event_data *event_data,
				     struct ima_field_data *field_data,
				     bool size_limit)
{
	const char *cur_filename = NULL;
	struct name_snapshot filename;
	u32 cur_filename_len = 0;
	bool snapshot = false;
	int ret;

	BUG_ON(event_data->filename == NULL && event_data->file == NULL);

	if (event_data->filename) {
		cur_filename = event_data->filename;
		cur_filename_len = strlen(event_data->filename);

		if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
			goto out;
	}

	if (event_data->file) {
		take_dentry_name_snapshot(&filename,
					  event_data->file->f_path.dentry);
		snapshot = true;
		cur_filename = filename.name.name;
		cur_filename_len = strlen(cur_filename);
	} else
		/*
		 * Truncate filename if the latter is too long and
		 * the file descriptor is not available.
		 */
		cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
out:
	ret = ima_write_template_field_data(cur_filename, cur_filename_len,
					    DATA_FMT_STRING, field_data);

	if (snapshot)
		release_dentry_name_snapshot(&filename);

	return ret;
}

/*
 * This function writes the name of an event (with size limit).
 */
int ima_eventname_init(struct ima_event_data *event_data,
		       struct ima_field_data *field_data)
{
	return ima_eventname_init_common(event_data, field_data, true);
}

/*
 * This function writes the name of an event (without size limit).
 */
int ima_eventname_ng_init(struct ima_event_data *event_data,
			  struct ima_field_data *field_data)
{
	return ima_eventname_init_common(event_data, field_data, false);
}

/*
 *  ima_eventsig_init - include the file signature as part of the template data
 */
int ima_eventsig_init(struct ima_event_data *event_data,
		      struct ima_field_data *field_data)
{
	struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;

	if (!xattr_value ||
	    (xattr_value->type != EVM_IMA_XATTR_DIGSIG &&
	     xattr_value->type != IMA_VERITY_DIGSIG))
		return ima_eventevmsig_init(event_data, field_data);

	return ima_write_template_field_data(xattr_value, event_data->xattr_len,
					     DATA_FMT_HEX, field_data);
}

/*
 *  ima_eventbuf_init - include the buffer(kexec-cmldine) as part of the
 *  template data.
 */
int ima_eventbuf_init(struct ima_event_data *event_data,
		      struct ima_field_data *field_data)
{
	if ((!event_data->buf) || (event_data->buf_len == 0))
		return 0;

	return ima_write_template_field_data(event_data->buf,
					     event_data->buf_len, DATA_FMT_HEX,
					     field_data);
}

/*
 *  ima_eventmodsig_init - include the appended file signature as part of the
 *  template data
 */
int ima_eventmodsig_init(struct ima_event_data *event_data,
			 struct ima_field_data *field_data)
{
	const void *data;
	u32 data_len;
	int rc;

	if (!event_data->modsig)
		return 0;

	/*
	 * modsig is a runtime structure containing pointers. Get its raw data
	 * instead.
	 */
	rc = ima_get_raw_modsig(event_data->modsig, &data, &data_len);
	if (rc)
		return rc;

	return ima_write_template_field_data(data, data_len, DATA_FMT_HEX,
					     field_data);
}

/*
 *  ima_eventevmsig_init - include the EVM portable signature as part of the
 *  template data
 */
int ima_eventevmsig_init(struct ima_event_data *event_data,
			 struct ima_field_data *field_data)
{
	struct evm_ima_xattr_data *xattr_data = NULL;
	int rc = 0;

	if (!event_data->file)
		return 0;

	rc = vfs_getxattr_alloc(&nop_mnt_idmap, file_dentry(event_data->file),
				XATTR_NAME_EVM, (char **)&xattr_data, 0,
				GFP_NOFS);
	if (rc <= 0 || xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG) {
		rc = 0;
		goto out;
	}

	rc = ima_write_template_field_data((char *)xattr_data, rc, DATA_FMT_HEX,
					   field_data);

out:
	kfree(xattr_data);
	return rc;
}

static int ima_eventinodedac_init_common(struct ima_event_data *event_data,
					 struct ima_field_data *field_data,
					 bool get_uid)
{
	unsigned int id;

	if (!event_data->file)
		return 0;

	if (get_uid)
		id = i_uid_read(file_inode(event_data->file));
	else
		id = i_gid_read(file_inode(event_data->file));

	if (ima_canonical_fmt) {
		if (sizeof(id) == sizeof(u16))
			id = (__force u16)cpu_to_le16(id);
		else
			id = (__force u32)cpu_to_le32(id);
	}

	return ima_write_template_field_data((void *)&id, sizeof(id),
					     DATA_FMT_UINT, field_data);
}

/*
 *  ima_eventinodeuid_init - include the inode UID as part of the template
 *  data
 */
int ima_eventinodeuid_init(struct ima_event_data *event_data,
			   struct ima_field_data *field_data)
{
	return ima_eventinodedac_init_common(event_data, field_data, true);
}

/*
 *  ima_eventinodegid_init - include the inode GID as part of the template
 *  data
 */
int ima_eventinodegid_init(struct ima_event_data *event_data,
			   struct ima_field_data *field_data)
{
	return ima_eventinodedac_init_common(event_data, field_data, false);
}

/*
 *  ima_eventinodemode_init - include the inode mode as part of the template
 *  data
 */
int ima_eventinodemode_init(struct ima_event_data *event_data,
			    struct ima_field_data *field_data)
{
	struct inode *inode;
	u16 mode;

	if (!event_data->file)
		return 0;

	inode = file_inode(event_data->file);
	mode = inode->i_mode;
	if (ima_canonical_fmt)
		mode = (__force u16)cpu_to_le16(mode);

	return ima_write_template_field_data((char *)&mode, sizeof(mode),
					     DATA_FMT_UINT, field_data);
}

static int ima_eventinodexattrs_init_common(struct ima_event_data *event_data,
					    struct ima_field_data *field_data,
					    char type)
{
	u8 *buffer = NULL;
	int rc;

	if (!event_data->file)
		return 0;

	rc = evm_read_protected_xattrs(file_dentry(event_data->file), NULL, 0,
				       type, ima_canonical_fmt);
	if (rc < 0)
		return 0;

	buffer = kmalloc(rc, GFP_KERNEL);
	if (!buffer)
		return 0;

	rc = evm_read_protected_xattrs(file_dentry(event_data->file), buffer,
				       rc, type, ima_canonical_fmt);
	if (rc < 0) {
		rc = 0;
		goto out;
	}

	rc = ima_write_template_field_data((char *)buffer, rc, DATA_FMT_HEX,
					   field_data);
out:
	kfree(buffer);
	return rc;
}

/*
 *  ima_eventinodexattrnames_init - include a list of xattr names as part of the
 *  template data
 */
int ima_eventinodexattrnames_init(struct ima_event_data *event_data,
				  struct ima_field_data *field_data)
{
	return ima_eventinodexattrs_init_common(event_data, field_data, 'n');
}

/*
 *  ima_eventinodexattrlengths_init - include a list of xattr lengths as part of
 *  the template data
 */
int ima_eventinodexattrlengths_init(struct ima_event_data *event_data,
				    struct ima_field_data *field_data)
{
	return ima_eventinodexattrs_init_common(event_data, field_data, 'l');
}

/*
 *  ima_eventinodexattrvalues_init - include a list of xattr values as part of
 *  the template data
 */
int ima_eventinodexattrvalues_init(struct ima_event_data *event_data,
				   struct ima_field_data *field_data)
{
	return ima_eventinodexattrs_init_common(event_data, field_data, 'v');
}
