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 <crypto/hash.h> 14 #include <crypto/sha.h> 15 #include <crypto/algapi.h> 16 #include <keys/user-type.h> 17 18 #include "ubifs.h" 19 20 /** 21 * ubifs_node_calc_hash - calculate the hash of a UBIFS node 22 * @c: UBIFS file-system description object 23 * @node: the node to calculate a hash for 24 * @hash: the returned hash 25 * 26 * Returns 0 for success or a negative error code otherwise. 27 */ 28 int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *node, 29 u8 *hash) 30 { 31 const struct ubifs_ch *ch = node; 32 SHASH_DESC_ON_STACK(shash, c->hash_tfm); 33 int err; 34 35 shash->tfm = c->hash_tfm; 36 shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 37 38 err = crypto_shash_digest(shash, node, le32_to_cpu(ch->len), hash); 39 if (err < 0) 40 return err; 41 return 0; 42 } 43 44 /** 45 * ubifs_hash_calc_hmac - calculate a HMAC from a hash 46 * @c: UBIFS file-system description object 47 * @hash: the node to calculate a HMAC for 48 * @hmac: the returned HMAC 49 * 50 * Returns 0 for success or a negative error code otherwise. 51 */ 52 static int ubifs_hash_calc_hmac(const struct ubifs_info *c, const u8 *hash, 53 u8 *hmac) 54 { 55 SHASH_DESC_ON_STACK(shash, c->hmac_tfm); 56 int err; 57 58 shash->tfm = c->hmac_tfm; 59 shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 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 SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm); 82 struct ubifs_auth_node *auth = node; 83 u8 *hash; 84 int err; 85 86 hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS); 87 if (!hash) 88 return -ENOMEM; 89 90 hash_desc->tfm = c->hash_tfm; 91 hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 92 ubifs_shash_copy_state(c, inhash, hash_desc); 93 94 err = crypto_shash_final(hash_desc, hash); 95 if (err) 96 goto out; 97 98 err = ubifs_hash_calc_hmac(c, hash, auth->hmac); 99 if (err) 100 goto out; 101 102 auth->ch.node_type = UBIFS_AUTH_NODE; 103 ubifs_prepare_node(c, auth, ubifs_auth_node_sz(c), 0); 104 105 err = 0; 106 out: 107 kfree(hash); 108 109 return err; 110 } 111 112 static struct shash_desc *ubifs_get_desc(const struct ubifs_info *c, 113 struct crypto_shash *tfm) 114 { 115 struct shash_desc *desc; 116 int err; 117 118 if (!ubifs_authenticated(c)) 119 return NULL; 120 121 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); 122 if (!desc) 123 return ERR_PTR(-ENOMEM); 124 125 desc->tfm = tfm; 126 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 127 128 err = crypto_shash_init(desc); 129 if (err) { 130 kfree(desc); 131 return ERR_PTR(err); 132 } 133 134 return desc; 135 } 136 137 /** 138 * __ubifs_hash_get_desc - get a descriptor suitable for hashing a node 139 * @c: UBIFS file-system description object 140 * 141 * This function returns a descriptor suitable for hashing a node. Free after use 142 * with kfree. 143 */ 144 struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c) 145 { 146 return ubifs_get_desc(c, c->hash_tfm); 147 } 148 149 /** 150 * __ubifs_shash_final - finalize shash 151 * @c: UBIFS file-system description object 152 * @desc: the descriptor 153 * @out: the output hash 154 * 155 * Simple wrapper around crypto_shash_final(), safe to be called with 156 * disabled authentication. 157 */ 158 int __ubifs_shash_final(const struct ubifs_info *c, struct shash_desc *desc, 159 u8 *out) 160 { 161 if (ubifs_authenticated(c)) 162 return crypto_shash_final(desc, out); 163 164 return 0; 165 } 166 167 /** 168 * ubifs_bad_hash - Report hash mismatches 169 * @c: UBIFS file-system description object 170 * @node: the node 171 * @hash: the expected hash 172 * @lnum: the LEB @node was read from 173 * @offs: offset in LEB @node was read from 174 * 175 * This function reports a hash mismatch when a node has a different hash than 176 * expected. 177 */ 178 void ubifs_bad_hash(const struct ubifs_info *c, const void *node, const u8 *hash, 179 int lnum, int offs) 180 { 181 int len = min(c->hash_len, 20); 182 int cropped = len != c->hash_len; 183 const char *cont = cropped ? "..." : ""; 184 185 u8 calc[UBIFS_HASH_ARR_SZ]; 186 187 __ubifs_node_calc_hash(c, node, calc); 188 189 ubifs_err(c, "hash mismatch on node at LEB %d:%d", lnum, offs); 190 ubifs_err(c, "hash expected: %*ph%s", len, hash, cont); 191 ubifs_err(c, "hash calculated: %*ph%s", len, calc, cont); 192 } 193 194 /** 195 * __ubifs_node_check_hash - check the hash of a node against given hash 196 * @c: UBIFS file-system description object 197 * @node: the node 198 * @expected: the expected hash 199 * 200 * This function calculates a hash over a node and compares it to the given hash. 201 * Returns 0 if both hashes are equal or authentication is disabled, otherwise a 202 * negative error code is returned. 203 */ 204 int __ubifs_node_check_hash(const struct ubifs_info *c, const void *node, 205 const u8 *expected) 206 { 207 u8 calc[UBIFS_HASH_ARR_SZ]; 208 int err; 209 210 err = __ubifs_node_calc_hash(c, node, calc); 211 if (err) 212 return err; 213 214 if (ubifs_check_hash(c, expected, calc)) 215 return -EPERM; 216 217 return 0; 218 } 219 220 /** 221 * ubifs_init_authentication - initialize UBIFS authentication support 222 * @c: UBIFS file-system description object 223 * 224 * This function returns 0 for success or a negative error code otherwise. 225 */ 226 int ubifs_init_authentication(struct ubifs_info *c) 227 { 228 struct key *keyring_key; 229 const struct user_key_payload *ukp; 230 int err; 231 char hmac_name[CRYPTO_MAX_ALG_NAME]; 232 233 if (!c->auth_hash_name) { 234 ubifs_err(c, "authentication hash name needed with authentication"); 235 return -EINVAL; 236 } 237 238 c->auth_hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST, 239 c->auth_hash_name); 240 if ((int)c->auth_hash_algo < 0) { 241 ubifs_err(c, "Unknown hash algo %s specified", 242 c->auth_hash_name); 243 return -EINVAL; 244 } 245 246 snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", 247 c->auth_hash_name); 248 249 keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL); 250 251 if (IS_ERR(keyring_key)) { 252 ubifs_err(c, "Failed to request key: %ld", 253 PTR_ERR(keyring_key)); 254 return PTR_ERR(keyring_key); 255 } 256 257 down_read(&keyring_key->sem); 258 259 if (keyring_key->type != &key_type_logon) { 260 ubifs_err(c, "key type must be logon"); 261 err = -ENOKEY; 262 goto out; 263 } 264 265 ukp = user_key_payload_locked(keyring_key); 266 if (!ukp) { 267 /* key was revoked before we acquired its semaphore */ 268 err = -EKEYREVOKED; 269 goto out; 270 } 271 272 c->hash_tfm = crypto_alloc_shash(c->auth_hash_name, 0, 273 CRYPTO_ALG_ASYNC); 274 if (IS_ERR(c->hash_tfm)) { 275 err = PTR_ERR(c->hash_tfm); 276 ubifs_err(c, "Can not allocate %s: %d", 277 c->auth_hash_name, err); 278 goto out; 279 } 280 281 c->hash_len = crypto_shash_digestsize(c->hash_tfm); 282 if (c->hash_len > UBIFS_HASH_ARR_SZ) { 283 ubifs_err(c, "hash %s is bigger than maximum allowed hash size (%d > %d)", 284 c->auth_hash_name, c->hash_len, UBIFS_HASH_ARR_SZ); 285 err = -EINVAL; 286 goto out_free_hash; 287 } 288 289 c->hmac_tfm = crypto_alloc_shash(hmac_name, 0, CRYPTO_ALG_ASYNC); 290 if (IS_ERR(c->hmac_tfm)) { 291 err = PTR_ERR(c->hmac_tfm); 292 ubifs_err(c, "Can not allocate %s: %d", hmac_name, err); 293 goto out_free_hash; 294 } 295 296 c->hmac_desc_len = crypto_shash_digestsize(c->hmac_tfm); 297 if (c->hmac_desc_len > UBIFS_HMAC_ARR_SZ) { 298 ubifs_err(c, "hmac %s is bigger than maximum allowed hmac size (%d > %d)", 299 hmac_name, c->hmac_desc_len, UBIFS_HMAC_ARR_SZ); 300 err = -EINVAL; 301 goto out_free_hash; 302 } 303 304 err = crypto_shash_setkey(c->hmac_tfm, ukp->data, ukp->datalen); 305 if (err) 306 goto out_free_hmac; 307 308 c->authenticated = true; 309 310 c->log_hash = ubifs_hash_get_desc(c); 311 if (IS_ERR(c->log_hash)) 312 goto out_free_hmac; 313 314 err = 0; 315 316 out_free_hmac: 317 if (err) 318 crypto_free_shash(c->hmac_tfm); 319 out_free_hash: 320 if (err) 321 crypto_free_shash(c->hash_tfm); 322 out: 323 up_read(&keyring_key->sem); 324 key_put(keyring_key); 325 326 return err; 327 } 328 329 /** 330 * __ubifs_exit_authentication - release resource 331 * @c: UBIFS file-system description object 332 * 333 * This function releases the authentication related resources. 334 */ 335 void __ubifs_exit_authentication(struct ubifs_info *c) 336 { 337 if (!ubifs_authenticated(c)) 338 return; 339 340 crypto_free_shash(c->hmac_tfm); 341 crypto_free_shash(c->hash_tfm); 342 kfree(c->log_hash); 343 } 344 345 /** 346 * ubifs_node_calc_hmac - calculate the HMAC of a UBIFS node 347 * @c: UBIFS file-system description object 348 * @node: the node to insert a HMAC into. 349 * @len: the length of the node 350 * @ofs_hmac: the offset in the node where the HMAC is inserted 351 * @hmac: returned HMAC 352 * 353 * This function calculates a HMAC of a UBIFS node. The HMAC is expected to be 354 * embedded into the node, so this area is not covered by the HMAC. Also not 355 * covered is the UBIFS_NODE_MAGIC and the CRC of the node. 356 */ 357 static int ubifs_node_calc_hmac(const struct ubifs_info *c, const void *node, 358 int len, int ofs_hmac, void *hmac) 359 { 360 SHASH_DESC_ON_STACK(shash, c->hmac_tfm); 361 int hmac_len = c->hmac_desc_len; 362 int err; 363 364 ubifs_assert(c, ofs_hmac > 8); 365 ubifs_assert(c, ofs_hmac + hmac_len < len); 366 367 shash->tfm = c->hmac_tfm; 368 shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 369 370 err = crypto_shash_init(shash); 371 if (err) 372 return err; 373 374 /* behind common node header CRC up to HMAC begin */ 375 err = crypto_shash_update(shash, node + 8, ofs_hmac - 8); 376 if (err < 0) 377 return err; 378 379 /* behind HMAC, if any */ 380 if (len - ofs_hmac - hmac_len > 0) { 381 err = crypto_shash_update(shash, node + ofs_hmac + hmac_len, 382 len - ofs_hmac - hmac_len); 383 if (err < 0) 384 return err; 385 } 386 387 return crypto_shash_final(shash, hmac); 388 } 389 390 /** 391 * __ubifs_node_insert_hmac - insert a HMAC into a UBIFS node 392 * @c: UBIFS file-system description object 393 * @node: the node to insert a HMAC into. 394 * @len: the length of the node 395 * @ofs_hmac: the offset in the node where the HMAC is inserted 396 * 397 * This function inserts a HMAC at offset @ofs_hmac into the node given in 398 * @node. 399 * 400 * This function returns 0 for success or a negative error code otherwise. 401 */ 402 int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *node, int len, 403 int ofs_hmac) 404 { 405 return ubifs_node_calc_hmac(c, node, len, ofs_hmac, node + ofs_hmac); 406 } 407 408 /** 409 * __ubifs_node_verify_hmac - verify the HMAC of UBIFS node 410 * @c: UBIFS file-system description object 411 * @node: the node to insert a HMAC into. 412 * @len: the length of the node 413 * @ofs_hmac: the offset in the node where the HMAC is inserted 414 * 415 * This function verifies the HMAC at offset @ofs_hmac of the node given in 416 * @node. Returns 0 if successful or a negative error code otherwise. 417 */ 418 int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node, 419 int len, int ofs_hmac) 420 { 421 int hmac_len = c->hmac_desc_len; 422 u8 *hmac; 423 int err; 424 425 hmac = kmalloc(hmac_len, GFP_NOFS); 426 if (!hmac) 427 return -ENOMEM; 428 429 err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac); 430 if (err) 431 return err; 432 433 err = crypto_memneq(hmac, node + ofs_hmac, hmac_len); 434 435 kfree(hmac); 436 437 if (!err) 438 return 0; 439 440 return -EPERM; 441 } 442 443 int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src, 444 struct shash_desc *target) 445 { 446 u8 *state; 447 int err; 448 449 state = kmalloc(crypto_shash_descsize(src->tfm), GFP_NOFS); 450 if (!state) 451 return -ENOMEM; 452 453 err = crypto_shash_export(src, state); 454 if (err) 455 goto out; 456 457 err = crypto_shash_import(target, state); 458 459 out: 460 kfree(state); 461 462 return err; 463 } 464 465 /** 466 * ubifs_hmac_wkm - Create a HMAC of the well known message 467 * @c: UBIFS file-system description object 468 * @hmac: The HMAC of the well known message 469 * 470 * This function creates a HMAC of a well known message. This is used 471 * to check if the provided key is suitable to authenticate a UBIFS 472 * image. This is only a convenience to the user to provide a better 473 * error message when the wrong key is provided. 474 * 475 * This function returns 0 for success or a negative error code otherwise. 476 */ 477 int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac) 478 { 479 SHASH_DESC_ON_STACK(shash, c->hmac_tfm); 480 int err; 481 const char well_known_message[] = "UBIFS"; 482 483 if (!ubifs_authenticated(c)) 484 return 0; 485 486 shash->tfm = c->hmac_tfm; 487 shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 488 489 err = crypto_shash_init(shash); 490 if (err) 491 return err; 492 493 err = crypto_shash_update(shash, well_known_message, 494 sizeof(well_known_message) - 1); 495 if (err < 0) 496 return err; 497 498 err = crypto_shash_final(shash, hmac); 499 if (err) 500 return err; 501 return 0; 502 } 503