1 /*
2  * Copyright (C) 2013 Politecnico di Torino, Italy
3  *                    TORSEC group -- http://security.polito.it
4  *
5  * Author: Roberto Sassu <roberto.sassu@polito.it>
6  *
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
10  * License.
11  *
12  * File: ima_template_lib.c
13  *      Library of supported template fields.
14  */
15 #include <crypto/hash_info.h>
16 
17 #include "ima_template_lib.h"
18 
19 static bool ima_template_hash_algo_allowed(u8 algo)
20 {
21 	if (algo == HASH_ALGO_SHA1 || algo == HASH_ALGO_MD5)
22 		return true;
23 
24 	return false;
25 }
26 
27 enum data_formats {
28 	DATA_FMT_DIGEST = 0,
29 	DATA_FMT_DIGEST_WITH_ALGO,
30 	DATA_FMT_EVENT_NAME,
31 	DATA_FMT_STRING,
32 	DATA_FMT_HEX
33 };
34 
35 static int ima_write_template_field_data(const void *data, const u32 datalen,
36 					 enum data_formats datafmt,
37 					 struct ima_field_data *field_data)
38 {
39 	u8 *buf, *buf_ptr;
40 	u32 buflen;
41 
42 	switch (datafmt) {
43 	case DATA_FMT_EVENT_NAME:
44 		buflen = IMA_EVENT_NAME_LEN_MAX + 1;
45 		break;
46 	case DATA_FMT_STRING:
47 		buflen = datalen + 1;
48 		break;
49 	default:
50 		buflen = datalen;
51 	}
52 
53 	buf = kzalloc(buflen, GFP_KERNEL);
54 	if (!buf)
55 		return -ENOMEM;
56 
57 	memcpy(buf, data, datalen);
58 
59 	/*
60 	 * Replace all space characters with underscore for event names and
61 	 * strings. This avoid that, during the parsing of a measurements list,
62 	 * filenames with spaces or that end with the suffix ' (deleted)' are
63 	 * split into multiple template fields (the space is the delimitator
64 	 * character for measurements lists in ASCII format).
65 	 */
66 	if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) {
67 		for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++)
68 			if (*buf_ptr == ' ')
69 				*buf_ptr = '_';
70 	}
71 
72 	field_data->data = buf;
73 	field_data->len = buflen;
74 	return 0;
75 }
76 
77 static void ima_show_template_data_ascii(struct seq_file *m,
78 					 enum ima_show_type show,
79 					 enum data_formats datafmt,
80 					 struct ima_field_data *field_data)
81 {
82 	u8 *buf_ptr = field_data->data, buflen = field_data->len;
83 
84 	switch (datafmt) {
85 	case DATA_FMT_DIGEST_WITH_ALGO:
86 		buf_ptr = strnchr(field_data->data, buflen, ':');
87 		if (buf_ptr != field_data->data)
88 			seq_printf(m, "%s", field_data->data);
89 
90 		/* skip ':' and '\0' */
91 		buf_ptr += 2;
92 		buflen -= buf_ptr - field_data->data;
93 	case DATA_FMT_DIGEST:
94 	case DATA_FMT_HEX:
95 		if (!buflen)
96 			break;
97 		ima_print_digest(m, buf_ptr, buflen);
98 		break;
99 	case DATA_FMT_STRING:
100 		seq_printf(m, "%s", buf_ptr);
101 		break;
102 	default:
103 		break;
104 	}
105 }
106 
107 static void ima_show_template_data_binary(struct seq_file *m,
108 					  enum ima_show_type show,
109 					  enum data_formats datafmt,
110 					  struct ima_field_data *field_data)
111 {
112 	if (show != IMA_SHOW_BINARY_NO_FIELD_LEN)
113 		ima_putc(m, &field_data->len, sizeof(u32));
114 
115 	if (!field_data->len)
116 		return;
117 
118 	ima_putc(m, field_data->data, field_data->len);
119 }
120 
121 static void ima_show_template_field_data(struct seq_file *m,
122 					 enum ima_show_type show,
123 					 enum data_formats datafmt,
124 					 struct ima_field_data *field_data)
125 {
126 	switch (show) {
127 	case IMA_SHOW_ASCII:
128 		ima_show_template_data_ascii(m, show, datafmt, field_data);
129 		break;
130 	case IMA_SHOW_BINARY:
131 	case IMA_SHOW_BINARY_NO_FIELD_LEN:
132 		ima_show_template_data_binary(m, show, datafmt, field_data);
133 		break;
134 	default:
135 		break;
136 	}
137 }
138 
139 void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
140 			      struct ima_field_data *field_data)
141 {
142 	ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data);
143 }
144 
145 void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
146 				 struct ima_field_data *field_data)
147 {
148 	ima_show_template_field_data(m, show, DATA_FMT_DIGEST_WITH_ALGO,
149 				     field_data);
150 }
151 
152 void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
153 			      struct ima_field_data *field_data)
154 {
155 	ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data);
156 }
157 
158 void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
159 			   struct ima_field_data *field_data)
160 {
161 	ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
162 }
163 
164 static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
165 				       struct ima_field_data *field_data)
166 {
167 	/*
168 	 * digest formats:
169 	 *  - DATA_FMT_DIGEST: digest
170 	 *  - DATA_FMT_DIGEST_WITH_ALGO: [<hash algo>] + ':' + '\0' + digest,
171 	 *    where <hash algo> is provided if the hash algoritm is not
172 	 *    SHA1 or MD5
173 	 */
174 	u8 buffer[CRYPTO_MAX_ALG_NAME + 2 + IMA_MAX_DIGEST_SIZE] = { 0 };
175 	enum data_formats fmt = DATA_FMT_DIGEST;
176 	u32 offset = 0;
177 
178 	if (hash_algo < HASH_ALGO__LAST) {
179 		fmt = DATA_FMT_DIGEST_WITH_ALGO;
180 		offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s",
181 				   hash_algo_name[hash_algo]);
182 		buffer[offset] = ':';
183 		offset += 2;
184 	}
185 
186 	if (digest)
187 		memcpy(buffer + offset, digest, digestsize);
188 	else
189 		/*
190 		 * If digest is NULL, the event being recorded is a violation.
191 		 * Make room for the digest by increasing the offset of
192 		 * IMA_DIGEST_SIZE.
193 		 */
194 		offset += IMA_DIGEST_SIZE;
195 
196 	return ima_write_template_field_data(buffer, offset + digestsize,
197 					     fmt, field_data);
198 }
199 
200 /*
201  * This function writes the digest of an event (with size limit).
202  */
203 int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
204 			 const unsigned char *filename,
205 			 struct evm_ima_xattr_data *xattr_value, int xattr_len,
206 			 struct ima_field_data *field_data)
207 {
208 	struct {
209 		struct ima_digest_data hdr;
210 		char digest[IMA_MAX_DIGEST_SIZE];
211 	} hash;
212 	u8 *cur_digest = NULL;
213 	u32 cur_digestsize = 0;
214 	struct inode *inode;
215 	int result;
216 
217 	memset(&hash, 0, sizeof(hash));
218 
219 	if (!iint)		/* recording a violation. */
220 		goto out;
221 
222 	if (ima_template_hash_algo_allowed(iint->ima_hash->algo)) {
223 		cur_digest = iint->ima_hash->digest;
224 		cur_digestsize = iint->ima_hash->length;
225 		goto out;
226 	}
227 
228 	if (!file)		/* missing info to re-calculate the digest */
229 		return -EINVAL;
230 
231 	inode = file_inode(file);
232 	hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
233 	    ima_hash_algo : HASH_ALGO_SHA1;
234 	result = ima_calc_file_hash(file, &hash.hdr);
235 	if (result) {
236 		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
237 				    filename, "collect_data",
238 				    "failed", result, 0);
239 		return result;
240 	}
241 	cur_digest = hash.hdr.digest;
242 	cur_digestsize = hash.hdr.length;
243 out:
244 	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
245 					   HASH_ALGO__LAST, field_data);
246 }
247 
248 /*
249  * This function writes the digest of an event (without size limit).
250  */
251 int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
252 			    struct file *file, const unsigned char *filename,
253 			    struct evm_ima_xattr_data *xattr_value,
254 			    int xattr_len, struct ima_field_data *field_data)
255 {
256 	u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
257 	u32 cur_digestsize = 0;
258 
259 	/* If iint is NULL, we are recording a violation. */
260 	if (!iint)
261 		goto out;
262 
263 	cur_digest = iint->ima_hash->digest;
264 	cur_digestsize = iint->ima_hash->length;
265 
266 	hash_algo = iint->ima_hash->algo;
267 out:
268 	return ima_eventdigest_init_common(cur_digest, cur_digestsize,
269 					   hash_algo, field_data);
270 }
271 
272 static int ima_eventname_init_common(struct integrity_iint_cache *iint,
273 				     struct file *file,
274 				     const unsigned char *filename,
275 				     struct ima_field_data *field_data,
276 				     bool size_limit)
277 {
278 	const char *cur_filename = NULL;
279 	u32 cur_filename_len = 0;
280 	enum data_formats fmt = size_limit ?
281 	    DATA_FMT_EVENT_NAME : DATA_FMT_STRING;
282 
283 	BUG_ON(filename == NULL && file == NULL);
284 
285 	if (filename) {
286 		cur_filename = filename;
287 		cur_filename_len = strlen(filename);
288 
289 		if (!size_limit || cur_filename_len <= IMA_EVENT_NAME_LEN_MAX)
290 			goto out;
291 	}
292 
293 	if (file) {
294 		cur_filename = file->f_dentry->d_name.name;
295 		cur_filename_len = strlen(cur_filename);
296 	} else
297 		/*
298 		 * Truncate filename if the latter is too long and
299 		 * the file descriptor is not available.
300 		 */
301 		cur_filename_len = IMA_EVENT_NAME_LEN_MAX;
302 out:
303 	return ima_write_template_field_data(cur_filename, cur_filename_len,
304 					     fmt, field_data);
305 }
306 
307 /*
308  * This function writes the name of an event (with size limit).
309  */
310 int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file,
311 		       const unsigned char *filename,
312 		       struct evm_ima_xattr_data *xattr_value, int xattr_len,
313 		       struct ima_field_data *field_data)
314 {
315 	return ima_eventname_init_common(iint, file, filename,
316 					 field_data, true);
317 }
318 
319 /*
320  * This function writes the name of an event (without size limit).
321  */
322 int ima_eventname_ng_init(struct integrity_iint_cache *iint, struct file *file,
323 			  const unsigned char *filename,
324 			  struct evm_ima_xattr_data *xattr_value, int xattr_len,
325 			  struct ima_field_data *field_data)
326 {
327 	return ima_eventname_init_common(iint, file, filename,
328 					 field_data, false);
329 }
330 
331 /*
332  *  ima_eventsig_init - include the file signature as part of the template data
333  */
334 int ima_eventsig_init(struct integrity_iint_cache *iint, struct file *file,
335 		      const unsigned char *filename,
336 		      struct evm_ima_xattr_data *xattr_value, int xattr_len,
337 		      struct ima_field_data *field_data)
338 {
339 	enum data_formats fmt = DATA_FMT_HEX;
340 	int rc = 0;
341 
342 	if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
343 		goto out;
344 
345 	rc = ima_write_template_field_data(xattr_value, xattr_len, fmt,
346 					   field_data);
347 out:
348 	return rc;
349 }
350