xref: /openbmc/linux/fs/ubifs/auth.c (revision 78beef62)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * This file is part of UBIFS.
4  *
5  * Copyright (C) 2018 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
6  */
7 
8 /*
9  * This file implements various helper functions for UBIFS authentication support
10  */
11 
12 #include <linux/crypto.h>
13 #include <linux/verification.h>
14 #include <crypto/hash.h>
15 #include <crypto/sha.h>
16 #include <crypto/algapi.h>
17 #include <keys/user-type.h>
18 #include <keys/asymmetric-type.h>
19 
20 #include "ubifs.h"
21 
22 /**
23  * ubifs_node_calc_hash - calculate the hash of a UBIFS node
24  * @c: UBIFS file-system description object
25  * @node: the node to calculate a hash for
26  * @hash: the returned hash
27  *
28  * Returns 0 for success or a negative error code otherwise.
29  */
30 int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *node,
31 			    u8 *hash)
32 {
33 	const struct ubifs_ch *ch = node;
34 	SHASH_DESC_ON_STACK(shash, c->hash_tfm);
35 	int err;
36 
37 	shash->tfm = c->hash_tfm;
38 
39 	err = crypto_shash_digest(shash, node, le32_to_cpu(ch->len), hash);
40 	if (err < 0)
41 		return err;
42 	return 0;
43 }
44 
45 /**
46  * ubifs_hash_calc_hmac - calculate a HMAC from a hash
47  * @c: UBIFS file-system description object
48  * @hash: the node to calculate a HMAC for
49  * @hmac: the returned HMAC
50  *
51  * Returns 0 for success or a negative error code otherwise.
52  */
53 static int ubifs_hash_calc_hmac(const struct ubifs_info *c, const u8 *hash,
54 				 u8 *hmac)
55 {
56 	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
57 	int err;
58 
59 	shash->tfm = c->hmac_tfm;
60 
61 	err = crypto_shash_digest(shash, hash, c->hash_len, hmac);
62 	if (err < 0)
63 		return err;
64 	return 0;
65 }
66 
67 /**
68  * ubifs_prepare_auth_node - Prepare an authentication node
69  * @c: UBIFS file-system description object
70  * @node: the node to calculate a hash for
71  * @hash: input hash of previous nodes
72  *
73  * This function prepares an authentication node for writing onto flash.
74  * It creates a HMAC from the given input hash and writes it to the node.
75  *
76  * Returns 0 for success or a negative error code otherwise.
77  */
78 int ubifs_prepare_auth_node(struct ubifs_info *c, void *node,
79 			     struct shash_desc *inhash)
80 {
81 	struct ubifs_auth_node *auth = node;
82 	u8 *hash;
83 	int err;
84 
85 	hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS);
86 	if (!hash)
87 		return -ENOMEM;
88 
89 	{
90 		SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm);
91 
92 		hash_desc->tfm = c->hash_tfm;
93 		ubifs_shash_copy_state(c, inhash, hash_desc);
94 
95 		err = crypto_shash_final(hash_desc, hash);
96 		if (err)
97 			goto out;
98 	}
99 
100 	err = ubifs_hash_calc_hmac(c, hash, auth->hmac);
101 	if (err)
102 		goto out;
103 
104 	auth->ch.node_type = UBIFS_AUTH_NODE;
105 	ubifs_prepare_node(c, auth, ubifs_auth_node_sz(c), 0);
106 
107 	err = 0;
108 out:
109 	kfree(hash);
110 
111 	return err;
112 }
113 
114 static struct shash_desc *ubifs_get_desc(const struct ubifs_info *c,
115 					 struct crypto_shash *tfm)
116 {
117 	struct shash_desc *desc;
118 	int err;
119 
120 	if (!ubifs_authenticated(c))
121 		return NULL;
122 
123 	desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
124 	if (!desc)
125 		return ERR_PTR(-ENOMEM);
126 
127 	desc->tfm = tfm;
128 
129 	err = crypto_shash_init(desc);
130 	if (err) {
131 		kfree(desc);
132 		return ERR_PTR(err);
133 	}
134 
135 	return desc;
136 }
137 
138 /**
139  * __ubifs_hash_get_desc - get a descriptor suitable for hashing a node
140  * @c: UBIFS file-system description object
141  *
142  * This function returns a descriptor suitable for hashing a node. Free after use
143  * with kfree.
144  */
145 struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c)
146 {
147 	return ubifs_get_desc(c, c->hash_tfm);
148 }
149 
150 /**
151  * ubifs_bad_hash - Report hash mismatches
152  * @c: UBIFS file-system description object
153  * @node: the node
154  * @hash: the expected hash
155  * @lnum: the LEB @node was read from
156  * @offs: offset in LEB @node was read from
157  *
158  * This function reports a hash mismatch when a node has a different hash than
159  * expected.
160  */
161 void ubifs_bad_hash(const struct ubifs_info *c, const void *node, const u8 *hash,
162 		    int lnum, int offs)
163 {
164 	int len = min(c->hash_len, 20);
165 	int cropped = len != c->hash_len;
166 	const char *cont = cropped ? "..." : "";
167 
168 	u8 calc[UBIFS_HASH_ARR_SZ];
169 
170 	__ubifs_node_calc_hash(c, node, calc);
171 
172 	ubifs_err(c, "hash mismatch on node at LEB %d:%d", lnum, offs);
173 	ubifs_err(c, "hash expected:   %*ph%s", len, hash, cont);
174 	ubifs_err(c, "hash calculated: %*ph%s", len, calc, cont);
175 }
176 
177 /**
178  * __ubifs_node_check_hash - check the hash of a node against given hash
179  * @c: UBIFS file-system description object
180  * @node: the node
181  * @expected: the expected hash
182  *
183  * This function calculates a hash over a node and compares it to the given hash.
184  * Returns 0 if both hashes are equal or authentication is disabled, otherwise a
185  * negative error code is returned.
186  */
187 int __ubifs_node_check_hash(const struct ubifs_info *c, const void *node,
188 			    const u8 *expected)
189 {
190 	u8 calc[UBIFS_HASH_ARR_SZ];
191 	int err;
192 
193 	err = __ubifs_node_calc_hash(c, node, calc);
194 	if (err)
195 		return err;
196 
197 	if (ubifs_check_hash(c, expected, calc))
198 		return -EPERM;
199 
200 	return 0;
201 }
202 
203 /**
204  * ubifs_sb_verify_signature - verify the signature of a superblock
205  * @c: UBIFS file-system description object
206  * @sup: The superblock node
207  *
208  * To support offline signed images the superblock can be signed with a
209  * PKCS#7 signature. The signature is placed directly behind the superblock
210  * node in an ubifs_sig_node.
211  *
212  * Returns 0 when the signature can be successfully verified or a negative
213  * error code if not.
214  */
215 int ubifs_sb_verify_signature(struct ubifs_info *c,
216 			      const struct ubifs_sb_node *sup)
217 {
218 	int err;
219 	struct ubifs_scan_leb *sleb;
220 	struct ubifs_scan_node *snod;
221 	const struct ubifs_sig_node *signode;
222 
223 	sleb = ubifs_scan(c, UBIFS_SB_LNUM, UBIFS_SB_NODE_SZ, c->sbuf, 0);
224 	if (IS_ERR(sleb)) {
225 		err = PTR_ERR(sleb);
226 		return err;
227 	}
228 
229 	if (sleb->nodes_cnt == 0) {
230 		ubifs_err(c, "Unable to find signature node");
231 		err = -EINVAL;
232 		goto out_destroy;
233 	}
234 
235 	snod = list_first_entry(&sleb->nodes, struct ubifs_scan_node, list);
236 
237 	if (snod->type != UBIFS_SIG_NODE) {
238 		ubifs_err(c, "Signature node is of wrong type");
239 		err = -EINVAL;
240 		goto out_destroy;
241 	}
242 
243 	signode = snod->node;
244 
245 	if (le32_to_cpu(signode->len) > snod->len + sizeof(struct ubifs_sig_node)) {
246 		ubifs_err(c, "invalid signature len %d", le32_to_cpu(signode->len));
247 		err = -EINVAL;
248 		goto out_destroy;
249 	}
250 
251 	if (le32_to_cpu(signode->type) != UBIFS_SIGNATURE_TYPE_PKCS7) {
252 		ubifs_err(c, "Signature type %d is not supported\n",
253 			  le32_to_cpu(signode->type));
254 		err = -EINVAL;
255 		goto out_destroy;
256 	}
257 
258 	err = verify_pkcs7_signature(sup, sizeof(struct ubifs_sb_node),
259 				     signode->sig, le32_to_cpu(signode->len),
260 				     NULL, VERIFYING_UNSPECIFIED_SIGNATURE,
261 				     NULL, NULL);
262 
263 	if (err)
264 		ubifs_err(c, "Failed to verify signature");
265 	else
266 		ubifs_msg(c, "Successfully verified super block signature");
267 
268 out_destroy:
269 	ubifs_scan_destroy(sleb);
270 
271 	return err;
272 }
273 
274 /**
275  * ubifs_init_authentication - initialize UBIFS authentication support
276  * @c: UBIFS file-system description object
277  *
278  * This function returns 0 for success or a negative error code otherwise.
279  */
280 int ubifs_init_authentication(struct ubifs_info *c)
281 {
282 	struct key *keyring_key;
283 	const struct user_key_payload *ukp;
284 	int err;
285 	char hmac_name[CRYPTO_MAX_ALG_NAME];
286 
287 	if (!c->auth_hash_name) {
288 		ubifs_err(c, "authentication hash name needed with authentication");
289 		return -EINVAL;
290 	}
291 
292 	c->auth_hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST,
293 					 c->auth_hash_name);
294 	if ((int)c->auth_hash_algo < 0) {
295 		ubifs_err(c, "Unknown hash algo %s specified",
296 			  c->auth_hash_name);
297 		return -EINVAL;
298 	}
299 
300 	snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
301 		 c->auth_hash_name);
302 
303 	keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL);
304 
305 	if (IS_ERR(keyring_key)) {
306 		ubifs_err(c, "Failed to request key: %ld",
307 			  PTR_ERR(keyring_key));
308 		return PTR_ERR(keyring_key);
309 	}
310 
311 	down_read(&keyring_key->sem);
312 
313 	if (keyring_key->type != &key_type_logon) {
314 		ubifs_err(c, "key type must be logon");
315 		err = -ENOKEY;
316 		goto out;
317 	}
318 
319 	ukp = user_key_payload_locked(keyring_key);
320 	if (!ukp) {
321 		/* key was revoked before we acquired its semaphore */
322 		err = -EKEYREVOKED;
323 		goto out;
324 	}
325 
326 	c->hash_tfm = crypto_alloc_shash(c->auth_hash_name, 0, 0);
327 	if (IS_ERR(c->hash_tfm)) {
328 		err = PTR_ERR(c->hash_tfm);
329 		ubifs_err(c, "Can not allocate %s: %d",
330 			  c->auth_hash_name, err);
331 		goto out;
332 	}
333 
334 	c->hash_len = crypto_shash_digestsize(c->hash_tfm);
335 	if (c->hash_len > UBIFS_HASH_ARR_SZ) {
336 		ubifs_err(c, "hash %s is bigger than maximum allowed hash size (%d > %d)",
337 			  c->auth_hash_name, c->hash_len, UBIFS_HASH_ARR_SZ);
338 		err = -EINVAL;
339 		goto out_free_hash;
340 	}
341 
342 	c->hmac_tfm = crypto_alloc_shash(hmac_name, 0, 0);
343 	if (IS_ERR(c->hmac_tfm)) {
344 		err = PTR_ERR(c->hmac_tfm);
345 		ubifs_err(c, "Can not allocate %s: %d", hmac_name, err);
346 		goto out_free_hash;
347 	}
348 
349 	c->hmac_desc_len = crypto_shash_digestsize(c->hmac_tfm);
350 	if (c->hmac_desc_len > UBIFS_HMAC_ARR_SZ) {
351 		ubifs_err(c, "hmac %s is bigger than maximum allowed hmac size (%d > %d)",
352 			  hmac_name, c->hmac_desc_len, UBIFS_HMAC_ARR_SZ);
353 		err = -EINVAL;
354 		goto out_free_hash;
355 	}
356 
357 	err = crypto_shash_setkey(c->hmac_tfm, ukp->data, ukp->datalen);
358 	if (err)
359 		goto out_free_hmac;
360 
361 	c->authenticated = true;
362 
363 	c->log_hash = ubifs_hash_get_desc(c);
364 	if (IS_ERR(c->log_hash))
365 		goto out_free_hmac;
366 
367 	err = 0;
368 
369 out_free_hmac:
370 	if (err)
371 		crypto_free_shash(c->hmac_tfm);
372 out_free_hash:
373 	if (err)
374 		crypto_free_shash(c->hash_tfm);
375 out:
376 	up_read(&keyring_key->sem);
377 	key_put(keyring_key);
378 
379 	return err;
380 }
381 
382 /**
383  * __ubifs_exit_authentication - release resource
384  * @c: UBIFS file-system description object
385  *
386  * This function releases the authentication related resources.
387  */
388 void __ubifs_exit_authentication(struct ubifs_info *c)
389 {
390 	if (!ubifs_authenticated(c))
391 		return;
392 
393 	crypto_free_shash(c->hmac_tfm);
394 	crypto_free_shash(c->hash_tfm);
395 	kfree(c->log_hash);
396 }
397 
398 /**
399  * ubifs_node_calc_hmac - calculate the HMAC of a UBIFS node
400  * @c: UBIFS file-system description object
401  * @node: the node to insert a HMAC into.
402  * @len: the length of the node
403  * @ofs_hmac: the offset in the node where the HMAC is inserted
404  * @hmac: returned HMAC
405  *
406  * This function calculates a HMAC of a UBIFS node. The HMAC is expected to be
407  * embedded into the node, so this area is not covered by the HMAC. Also not
408  * covered is the UBIFS_NODE_MAGIC and the CRC of the node.
409  */
410 static int ubifs_node_calc_hmac(const struct ubifs_info *c, const void *node,
411 				int len, int ofs_hmac, void *hmac)
412 {
413 	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
414 	int hmac_len = c->hmac_desc_len;
415 	int err;
416 
417 	ubifs_assert(c, ofs_hmac > 8);
418 	ubifs_assert(c, ofs_hmac + hmac_len < len);
419 
420 	shash->tfm = c->hmac_tfm;
421 
422 	err = crypto_shash_init(shash);
423 	if (err)
424 		return err;
425 
426 	/* behind common node header CRC up to HMAC begin */
427 	err = crypto_shash_update(shash, node + 8, ofs_hmac - 8);
428 	if (err < 0)
429 		return err;
430 
431 	/* behind HMAC, if any */
432 	if (len - ofs_hmac - hmac_len > 0) {
433 		err = crypto_shash_update(shash, node + ofs_hmac + hmac_len,
434 			    len - ofs_hmac - hmac_len);
435 		if (err < 0)
436 			return err;
437 	}
438 
439 	return crypto_shash_final(shash, hmac);
440 }
441 
442 /**
443  * __ubifs_node_insert_hmac - insert a HMAC into a UBIFS node
444  * @c: UBIFS file-system description object
445  * @node: the node to insert a HMAC into.
446  * @len: the length of the node
447  * @ofs_hmac: the offset in the node where the HMAC is inserted
448  *
449  * This function inserts a HMAC at offset @ofs_hmac into the node given in
450  * @node.
451  *
452  * This function returns 0 for success or a negative error code otherwise.
453  */
454 int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *node, int len,
455 			    int ofs_hmac)
456 {
457 	return ubifs_node_calc_hmac(c, node, len, ofs_hmac, node + ofs_hmac);
458 }
459 
460 /**
461  * __ubifs_node_verify_hmac - verify the HMAC of UBIFS node
462  * @c: UBIFS file-system description object
463  * @node: the node to insert a HMAC into.
464  * @len: the length of the node
465  * @ofs_hmac: the offset in the node where the HMAC is inserted
466  *
467  * This function verifies the HMAC at offset @ofs_hmac of the node given in
468  * @node. Returns 0 if successful or a negative error code otherwise.
469  */
470 int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node,
471 			     int len, int ofs_hmac)
472 {
473 	int hmac_len = c->hmac_desc_len;
474 	u8 *hmac;
475 	int err;
476 
477 	hmac = kmalloc(hmac_len, GFP_NOFS);
478 	if (!hmac)
479 		return -ENOMEM;
480 
481 	err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac);
482 	if (err)
483 		return err;
484 
485 	err = crypto_memneq(hmac, node + ofs_hmac, hmac_len);
486 
487 	kfree(hmac);
488 
489 	if (!err)
490 		return 0;
491 
492 	return -EPERM;
493 }
494 
495 int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src,
496 			     struct shash_desc *target)
497 {
498 	u8 *state;
499 	int err;
500 
501 	state = kmalloc(crypto_shash_descsize(src->tfm), GFP_NOFS);
502 	if (!state)
503 		return -ENOMEM;
504 
505 	err = crypto_shash_export(src, state);
506 	if (err)
507 		goto out;
508 
509 	err = crypto_shash_import(target, state);
510 
511 out:
512 	kfree(state);
513 
514 	return err;
515 }
516 
517 /**
518  * ubifs_hmac_wkm - Create a HMAC of the well known message
519  * @c: UBIFS file-system description object
520  * @hmac: The HMAC of the well known message
521  *
522  * This function creates a HMAC of a well known message. This is used
523  * to check if the provided key is suitable to authenticate a UBIFS
524  * image. This is only a convenience to the user to provide a better
525  * error message when the wrong key is provided.
526  *
527  * This function returns 0 for success or a negative error code otherwise.
528  */
529 int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac)
530 {
531 	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
532 	int err;
533 	const char well_known_message[] = "UBIFS";
534 
535 	if (!ubifs_authenticated(c))
536 		return 0;
537 
538 	shash->tfm = c->hmac_tfm;
539 
540 	err = crypto_shash_init(shash);
541 	if (err)
542 		return err;
543 
544 	err = crypto_shash_update(shash, well_known_message,
545 				  sizeof(well_known_message) - 1);
546 	if (err < 0)
547 		return err;
548 
549 	err = crypto_shash_final(shash, hmac);
550 	if (err)
551 		return err;
552 	return 0;
553 }
554 
555 /*
556  * ubifs_hmac_zero - test if a HMAC is zero
557  * @c: UBIFS file-system description object
558  * @hmac: the HMAC to test
559  *
560  * This function tests if a HMAC is zero and returns true if it is
561  * and false otherwise.
562  */
563 bool ubifs_hmac_zero(struct ubifs_info *c, const u8 *hmac)
564 {
565 	return !memchr_inv(hmac, 0, c->hmac_desc_len);
566 }
567