1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * NVMe over Fabrics DH-HMAC-CHAP authentication. 4 * Copyright (c) 2020 Hannes Reinecke, SUSE Software Solutions. 5 * All rights reserved. 6 */ 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 #include <linux/module.h> 9 #include <linux/init.h> 10 #include <linux/slab.h> 11 #include <linux/err.h> 12 #include <crypto/hash.h> 13 #include <linux/crc32.h> 14 #include <linux/base64.h> 15 #include <linux/ctype.h> 16 #include <linux/random.h> 17 #include <linux/nvme-auth.h> 18 #include <linux/nvme-keyring.h> 19 #include <linux/unaligned.h> 20 21 #include "nvmet.h" 22 23 int nvmet_auth_set_key(struct nvmet_host *host, const char *secret, 24 bool set_ctrl) 25 { 26 unsigned char key_hash; 27 char *dhchap_secret; 28 29 if (!strlen(secret)) { 30 if (set_ctrl) { 31 kfree(host->dhchap_ctrl_secret); 32 host->dhchap_ctrl_secret = NULL; 33 host->dhchap_ctrl_key_hash = 0; 34 } else { 35 kfree(host->dhchap_secret); 36 host->dhchap_secret = NULL; 37 host->dhchap_key_hash = 0; 38 } 39 return 0; 40 } 41 if (sscanf(secret, "DHHC-1:%hhd:%*s", &key_hash) != 1) 42 return -EINVAL; 43 if (key_hash > 3) { 44 pr_warn("Invalid DH-HMAC-CHAP hash id %d\n", 45 key_hash); 46 return -EINVAL; 47 } 48 if (key_hash > 0) { 49 /* Validate selected hash algorithm */ 50 const char *hmac = nvme_auth_hmac_name(key_hash); 51 52 if (!crypto_has_shash(hmac, 0, 0)) { 53 pr_err("DH-HMAC-CHAP hash %s unsupported\n", hmac); 54 return -ENOTSUPP; 55 } 56 } 57 dhchap_secret = kstrdup(secret, GFP_KERNEL); 58 if (!dhchap_secret) 59 return -ENOMEM; 60 down_write(&nvmet_config_sem); 61 if (set_ctrl) { 62 kfree(host->dhchap_ctrl_secret); 63 host->dhchap_ctrl_secret = strim(dhchap_secret); 64 host->dhchap_ctrl_key_hash = key_hash; 65 } else { 66 kfree(host->dhchap_secret); 67 host->dhchap_secret = strim(dhchap_secret); 68 host->dhchap_key_hash = key_hash; 69 } 70 up_write(&nvmet_config_sem); 71 return 0; 72 } 73 74 int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id) 75 { 76 const char *dhgroup_kpp; 77 int ret = 0; 78 79 pr_debug("%s: ctrl %d selecting dhgroup %d\n", 80 __func__, ctrl->cntlid, dhgroup_id); 81 82 if (ctrl->dh_tfm) { 83 if (ctrl->dh_gid == dhgroup_id) { 84 pr_debug("%s: ctrl %d reuse existing DH group %d\n", 85 __func__, ctrl->cntlid, dhgroup_id); 86 return 0; 87 } 88 crypto_free_kpp(ctrl->dh_tfm); 89 ctrl->dh_tfm = NULL; 90 ctrl->dh_gid = 0; 91 } 92 93 if (dhgroup_id == NVME_AUTH_DHGROUP_NULL) 94 return 0; 95 96 dhgroup_kpp = nvme_auth_dhgroup_kpp(dhgroup_id); 97 if (!dhgroup_kpp) { 98 pr_debug("%s: ctrl %d invalid DH group %d\n", 99 __func__, ctrl->cntlid, dhgroup_id); 100 return -EINVAL; 101 } 102 ctrl->dh_tfm = crypto_alloc_kpp(dhgroup_kpp, 0, 0); 103 if (IS_ERR(ctrl->dh_tfm)) { 104 pr_debug("%s: ctrl %d failed to setup DH group %d, err %ld\n", 105 __func__, ctrl->cntlid, dhgroup_id, 106 PTR_ERR(ctrl->dh_tfm)); 107 ret = PTR_ERR(ctrl->dh_tfm); 108 ctrl->dh_tfm = NULL; 109 ctrl->dh_gid = 0; 110 } else { 111 ctrl->dh_gid = dhgroup_id; 112 pr_debug("%s: ctrl %d setup DH group %d\n", 113 __func__, ctrl->cntlid, ctrl->dh_gid); 114 ret = nvme_auth_gen_privkey(ctrl->dh_tfm, ctrl->dh_gid); 115 if (ret < 0) { 116 pr_debug("%s: ctrl %d failed to generate private key, err %d\n", 117 __func__, ctrl->cntlid, ret); 118 kfree_sensitive(ctrl->dh_key); 119 ctrl->dh_key = NULL; 120 return ret; 121 } 122 ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm); 123 kfree_sensitive(ctrl->dh_key); 124 ctrl->dh_key = kzalloc(ctrl->dh_keysize, GFP_KERNEL); 125 if (!ctrl->dh_key) { 126 pr_warn("ctrl %d failed to allocate public key\n", 127 ctrl->cntlid); 128 return -ENOMEM; 129 } 130 ret = nvme_auth_gen_pubkey(ctrl->dh_tfm, ctrl->dh_key, 131 ctrl->dh_keysize); 132 if (ret < 0) { 133 pr_warn("ctrl %d failed to generate public key\n", 134 ctrl->cntlid); 135 kfree(ctrl->dh_key); 136 ctrl->dh_key = NULL; 137 } 138 } 139 140 return ret; 141 } 142 143 u8 nvmet_setup_auth(struct nvmet_ctrl *ctrl, struct nvmet_sq *sq) 144 { 145 int ret = 0; 146 struct nvmet_host_link *p; 147 struct nvmet_host *host = NULL; 148 149 down_read(&nvmet_config_sem); 150 if (nvmet_is_disc_subsys(ctrl->subsys)) 151 goto out_unlock; 152 153 if (ctrl->subsys->allow_any_host) 154 goto out_unlock; 155 156 list_for_each_entry(p, &ctrl->subsys->hosts, entry) { 157 pr_debug("check %s\n", nvmet_host_name(p->host)); 158 if (strcmp(nvmet_host_name(p->host), ctrl->hostnqn)) 159 continue; 160 host = p->host; 161 break; 162 } 163 if (!host) { 164 pr_debug("host %s not found\n", ctrl->hostnqn); 165 ret = NVME_AUTH_DHCHAP_FAILURE_FAILED; 166 goto out_unlock; 167 } 168 169 if (nvmet_queue_tls_keyid(sq)) { 170 pr_debug("host %s tls enabled\n", ctrl->hostnqn); 171 goto out_unlock; 172 } 173 174 ret = nvmet_setup_dhgroup(ctrl, host->dhchap_dhgroup_id); 175 if (ret < 0) { 176 pr_warn("Failed to setup DH group"); 177 ret = NVME_AUTH_DHCHAP_FAILURE_DHGROUP_UNUSABLE; 178 goto out_unlock; 179 } 180 181 if (!host->dhchap_secret) { 182 pr_debug("No authentication provided\n"); 183 goto out_unlock; 184 } 185 186 if (host->dhchap_hash_id == ctrl->shash_id) { 187 pr_debug("Re-use existing hash ID %d\n", 188 ctrl->shash_id); 189 } else { 190 ctrl->shash_id = host->dhchap_hash_id; 191 } 192 193 /* Skip the 'DHHC-1:XX:' prefix */ 194 nvme_auth_free_key(ctrl->host_key); 195 ctrl->host_key = nvme_auth_extract_key(host->dhchap_secret + 10, 196 host->dhchap_key_hash); 197 if (IS_ERR(ctrl->host_key)) { 198 ret = NVME_AUTH_DHCHAP_FAILURE_NOT_USABLE; 199 ctrl->host_key = NULL; 200 goto out_free_hash; 201 } 202 pr_debug("%s: using hash %s key %*ph\n", __func__, 203 ctrl->host_key->hash > 0 ? 204 nvme_auth_hmac_name(ctrl->host_key->hash) : "none", 205 (int)ctrl->host_key->len, ctrl->host_key->key); 206 207 nvme_auth_free_key(ctrl->ctrl_key); 208 if (!host->dhchap_ctrl_secret) { 209 ctrl->ctrl_key = NULL; 210 goto out_unlock; 211 } 212 213 ctrl->ctrl_key = nvme_auth_extract_key(host->dhchap_ctrl_secret + 10, 214 host->dhchap_ctrl_key_hash); 215 if (IS_ERR(ctrl->ctrl_key)) { 216 ret = NVME_AUTH_DHCHAP_FAILURE_NOT_USABLE; 217 ctrl->ctrl_key = NULL; 218 goto out_free_hash; 219 } 220 pr_debug("%s: using ctrl hash %s key %*ph\n", __func__, 221 ctrl->ctrl_key->hash > 0 ? 222 nvme_auth_hmac_name(ctrl->ctrl_key->hash) : "none", 223 (int)ctrl->ctrl_key->len, ctrl->ctrl_key->key); 224 225 out_free_hash: 226 if (ret) { 227 if (ctrl->host_key) { 228 nvme_auth_free_key(ctrl->host_key); 229 ctrl->host_key = NULL; 230 } 231 ctrl->shash_id = 0; 232 } 233 out_unlock: 234 up_read(&nvmet_config_sem); 235 236 return ret; 237 } 238 239 void nvmet_auth_sq_free(struct nvmet_sq *sq) 240 { 241 cancel_delayed_work(&sq->auth_expired_work); 242 #ifdef CONFIG_NVME_TARGET_TCP_TLS 243 sq->tls_key = NULL; 244 #endif 245 kfree(sq->dhchap_c1); 246 sq->dhchap_c1 = NULL; 247 kfree(sq->dhchap_c2); 248 sq->dhchap_c2 = NULL; 249 kfree(sq->dhchap_skey); 250 sq->dhchap_skey = NULL; 251 } 252 253 void nvmet_destroy_auth(struct nvmet_ctrl *ctrl) 254 { 255 ctrl->shash_id = 0; 256 257 if (ctrl->dh_tfm) { 258 crypto_free_kpp(ctrl->dh_tfm); 259 ctrl->dh_tfm = NULL; 260 ctrl->dh_gid = 0; 261 } 262 kfree_sensitive(ctrl->dh_key); 263 ctrl->dh_key = NULL; 264 265 if (ctrl->host_key) { 266 nvme_auth_free_key(ctrl->host_key); 267 ctrl->host_key = NULL; 268 } 269 if (ctrl->ctrl_key) { 270 nvme_auth_free_key(ctrl->ctrl_key); 271 ctrl->ctrl_key = NULL; 272 } 273 #ifdef CONFIG_NVME_TARGET_TCP_TLS 274 if (ctrl->tls_key) { 275 key_put(ctrl->tls_key); 276 ctrl->tls_key = NULL; 277 } 278 #endif 279 } 280 281 bool nvmet_check_auth_status(struct nvmet_req *req) 282 { 283 if (req->sq->ctrl->host_key && 284 !req->sq->authenticated) 285 return false; 286 return true; 287 } 288 289 int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response, 290 unsigned int shash_len) 291 { 292 struct crypto_shash *shash_tfm; 293 struct shash_desc *shash; 294 struct nvmet_ctrl *ctrl = req->sq->ctrl; 295 const char *hash_name; 296 u8 *challenge = req->sq->dhchap_c1; 297 struct nvme_dhchap_key *transformed_key; 298 u8 buf[4]; 299 int ret; 300 301 hash_name = nvme_auth_hmac_name(ctrl->shash_id); 302 if (!hash_name) { 303 pr_warn("Hash ID %d invalid\n", ctrl->shash_id); 304 return -EINVAL; 305 } 306 307 shash_tfm = crypto_alloc_shash(hash_name, 0, 0); 308 if (IS_ERR(shash_tfm)) { 309 pr_err("failed to allocate shash %s\n", hash_name); 310 return PTR_ERR(shash_tfm); 311 } 312 313 if (shash_len != crypto_shash_digestsize(shash_tfm)) { 314 pr_err("%s: hash len mismatch (len %d digest %d)\n", 315 __func__, shash_len, 316 crypto_shash_digestsize(shash_tfm)); 317 ret = -EINVAL; 318 goto out_free_tfm; 319 } 320 321 transformed_key = nvme_auth_transform_key(ctrl->host_key, 322 ctrl->hostnqn); 323 if (IS_ERR(transformed_key)) { 324 ret = PTR_ERR(transformed_key); 325 goto out_free_tfm; 326 } 327 328 ret = crypto_shash_setkey(shash_tfm, transformed_key->key, 329 transformed_key->len); 330 if (ret) 331 goto out_free_response; 332 333 if (ctrl->dh_gid != NVME_AUTH_DHGROUP_NULL) { 334 challenge = kmalloc(shash_len, GFP_KERNEL); 335 if (!challenge) { 336 ret = -ENOMEM; 337 goto out_free_response; 338 } 339 ret = nvme_auth_augmented_challenge(ctrl->shash_id, 340 req->sq->dhchap_skey, 341 req->sq->dhchap_skey_len, 342 req->sq->dhchap_c1, 343 challenge, shash_len); 344 if (ret) 345 goto out_free_challenge; 346 } 347 348 pr_debug("ctrl %d qid %d host response seq %u transaction %d\n", 349 ctrl->cntlid, req->sq->qid, req->sq->dhchap_s1, 350 req->sq->dhchap_tid); 351 352 shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(shash_tfm), 353 GFP_KERNEL); 354 if (!shash) { 355 ret = -ENOMEM; 356 goto out_free_challenge; 357 } 358 shash->tfm = shash_tfm; 359 ret = crypto_shash_init(shash); 360 if (ret) 361 goto out; 362 ret = crypto_shash_update(shash, challenge, shash_len); 363 if (ret) 364 goto out; 365 put_unaligned_le32(req->sq->dhchap_s1, buf); 366 ret = crypto_shash_update(shash, buf, 4); 367 if (ret) 368 goto out; 369 put_unaligned_le16(req->sq->dhchap_tid, buf); 370 ret = crypto_shash_update(shash, buf, 2); 371 if (ret) 372 goto out; 373 memset(buf, 0, 4); 374 ret = crypto_shash_update(shash, buf, 1); 375 if (ret) 376 goto out; 377 ret = crypto_shash_update(shash, "HostHost", 8); 378 if (ret) 379 goto out; 380 ret = crypto_shash_update(shash, ctrl->hostnqn, strlen(ctrl->hostnqn)); 381 if (ret) 382 goto out; 383 ret = crypto_shash_update(shash, buf, 1); 384 if (ret) 385 goto out; 386 ret = crypto_shash_update(shash, ctrl->subsysnqn, 387 strlen(ctrl->subsysnqn)); 388 if (ret) 389 goto out; 390 ret = crypto_shash_final(shash, response); 391 out: 392 kfree(shash); 393 out_free_challenge: 394 if (challenge != req->sq->dhchap_c1) 395 kfree(challenge); 396 out_free_response: 397 nvme_auth_free_key(transformed_key); 398 out_free_tfm: 399 crypto_free_shash(shash_tfm); 400 return ret; 401 } 402 403 int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response, 404 unsigned int shash_len) 405 { 406 struct crypto_shash *shash_tfm; 407 struct shash_desc *shash; 408 struct nvmet_ctrl *ctrl = req->sq->ctrl; 409 const char *hash_name; 410 u8 *challenge = req->sq->dhchap_c2; 411 struct nvme_dhchap_key *transformed_key; 412 u8 buf[4]; 413 int ret; 414 415 hash_name = nvme_auth_hmac_name(ctrl->shash_id); 416 if (!hash_name) { 417 pr_warn("Hash ID %d invalid\n", ctrl->shash_id); 418 return -EINVAL; 419 } 420 421 shash_tfm = crypto_alloc_shash(hash_name, 0, 0); 422 if (IS_ERR(shash_tfm)) { 423 pr_err("failed to allocate shash %s\n", hash_name); 424 return PTR_ERR(shash_tfm); 425 } 426 427 if (shash_len != crypto_shash_digestsize(shash_tfm)) { 428 pr_debug("%s: hash len mismatch (len %d digest %d)\n", 429 __func__, shash_len, 430 crypto_shash_digestsize(shash_tfm)); 431 ret = -EINVAL; 432 goto out_free_tfm; 433 } 434 435 transformed_key = nvme_auth_transform_key(ctrl->ctrl_key, 436 ctrl->subsysnqn); 437 if (IS_ERR(transformed_key)) { 438 ret = PTR_ERR(transformed_key); 439 goto out_free_tfm; 440 } 441 442 ret = crypto_shash_setkey(shash_tfm, transformed_key->key, 443 transformed_key->len); 444 if (ret) 445 goto out_free_response; 446 447 if (ctrl->dh_gid != NVME_AUTH_DHGROUP_NULL) { 448 challenge = kmalloc(shash_len, GFP_KERNEL); 449 if (!challenge) { 450 ret = -ENOMEM; 451 goto out_free_response; 452 } 453 ret = nvme_auth_augmented_challenge(ctrl->shash_id, 454 req->sq->dhchap_skey, 455 req->sq->dhchap_skey_len, 456 req->sq->dhchap_c2, 457 challenge, shash_len); 458 if (ret) 459 goto out_free_challenge; 460 } 461 462 shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(shash_tfm), 463 GFP_KERNEL); 464 if (!shash) { 465 ret = -ENOMEM; 466 goto out_free_challenge; 467 } 468 shash->tfm = shash_tfm; 469 470 ret = crypto_shash_init(shash); 471 if (ret) 472 goto out; 473 ret = crypto_shash_update(shash, challenge, shash_len); 474 if (ret) 475 goto out; 476 put_unaligned_le32(req->sq->dhchap_s2, buf); 477 ret = crypto_shash_update(shash, buf, 4); 478 if (ret) 479 goto out; 480 put_unaligned_le16(req->sq->dhchap_tid, buf); 481 ret = crypto_shash_update(shash, buf, 2); 482 if (ret) 483 goto out; 484 memset(buf, 0, 4); 485 ret = crypto_shash_update(shash, buf, 1); 486 if (ret) 487 goto out; 488 ret = crypto_shash_update(shash, "Controller", 10); 489 if (ret) 490 goto out; 491 ret = crypto_shash_update(shash, ctrl->subsysnqn, 492 strlen(ctrl->subsysnqn)); 493 if (ret) 494 goto out; 495 ret = crypto_shash_update(shash, buf, 1); 496 if (ret) 497 goto out; 498 ret = crypto_shash_update(shash, ctrl->hostnqn, strlen(ctrl->hostnqn)); 499 if (ret) 500 goto out; 501 ret = crypto_shash_final(shash, response); 502 out: 503 kfree(shash); 504 out_free_challenge: 505 if (challenge != req->sq->dhchap_c2) 506 kfree(challenge); 507 out_free_response: 508 nvme_auth_free_key(transformed_key); 509 out_free_tfm: 510 crypto_free_shash(shash_tfm); 511 return ret; 512 } 513 514 int nvmet_auth_ctrl_exponential(struct nvmet_req *req, 515 u8 *buf, int buf_size) 516 { 517 struct nvmet_ctrl *ctrl = req->sq->ctrl; 518 int ret = 0; 519 520 if (!ctrl->dh_key) { 521 pr_warn("ctrl %d no DH public key!\n", ctrl->cntlid); 522 return -ENOKEY; 523 } 524 if (buf_size != ctrl->dh_keysize) { 525 pr_warn("ctrl %d DH public key size mismatch, need %zu is %d\n", 526 ctrl->cntlid, ctrl->dh_keysize, buf_size); 527 ret = -EINVAL; 528 } else { 529 memcpy(buf, ctrl->dh_key, buf_size); 530 pr_debug("%s: ctrl %d public key %*ph\n", __func__, 531 ctrl->cntlid, (int)buf_size, buf); 532 } 533 534 return ret; 535 } 536 537 int nvmet_auth_ctrl_sesskey(struct nvmet_req *req, 538 u8 *pkey, int pkey_size) 539 { 540 struct nvmet_ctrl *ctrl = req->sq->ctrl; 541 int ret; 542 543 req->sq->dhchap_skey_len = ctrl->dh_keysize; 544 req->sq->dhchap_skey = kzalloc(req->sq->dhchap_skey_len, GFP_KERNEL); 545 if (!req->sq->dhchap_skey) 546 return -ENOMEM; 547 ret = nvme_auth_gen_shared_secret(ctrl->dh_tfm, 548 pkey, pkey_size, 549 req->sq->dhchap_skey, 550 req->sq->dhchap_skey_len); 551 if (ret) 552 pr_debug("failed to compute shared secret, err %d\n", ret); 553 else 554 pr_debug("%s: shared secret %*ph\n", __func__, 555 (int)req->sq->dhchap_skey_len, 556 req->sq->dhchap_skey); 557 558 return ret; 559 } 560 561 void nvmet_auth_insert_psk(struct nvmet_sq *sq) 562 { 563 int hash_len = nvme_auth_hmac_hash_len(sq->ctrl->shash_id); 564 u8 *psk, *digest, *tls_psk; 565 size_t psk_len; 566 int ret; 567 #ifdef CONFIG_NVME_TARGET_TCP_TLS 568 struct key *tls_key = NULL; 569 #endif 570 571 ret = nvme_auth_generate_psk(sq->ctrl->shash_id, 572 sq->dhchap_skey, 573 sq->dhchap_skey_len, 574 sq->dhchap_c1, sq->dhchap_c2, 575 hash_len, &psk, &psk_len); 576 if (ret) { 577 pr_warn("%s: ctrl %d qid %d failed to generate PSK, error %d\n", 578 __func__, sq->ctrl->cntlid, sq->qid, ret); 579 return; 580 } 581 ret = nvme_auth_generate_digest(sq->ctrl->shash_id, psk, psk_len, 582 sq->ctrl->subsysnqn, 583 sq->ctrl->hostnqn, &digest); 584 if (ret) { 585 pr_warn("%s: ctrl %d qid %d failed to generate digest, error %d\n", 586 __func__, sq->ctrl->cntlid, sq->qid, ret); 587 goto out_free_psk; 588 } 589 ret = nvme_auth_derive_tls_psk(sq->ctrl->shash_id, psk, psk_len, 590 digest, &tls_psk); 591 if (ret) { 592 pr_warn("%s: ctrl %d qid %d failed to derive TLS PSK, error %d\n", 593 __func__, sq->ctrl->cntlid, sq->qid, ret); 594 goto out_free_digest; 595 } 596 #ifdef CONFIG_NVME_TARGET_TCP_TLS 597 tls_key = nvme_tls_psk_refresh(NULL, sq->ctrl->hostnqn, sq->ctrl->subsysnqn, 598 sq->ctrl->shash_id, tls_psk, psk_len, digest); 599 if (IS_ERR(tls_key)) { 600 pr_warn("%s: ctrl %d qid %d failed to refresh key, error %ld\n", 601 __func__, sq->ctrl->cntlid, sq->qid, PTR_ERR(tls_key)); 602 tls_key = NULL; 603 } 604 if (sq->ctrl->tls_key) 605 key_put(sq->ctrl->tls_key); 606 sq->ctrl->tls_key = tls_key; 607 #endif 608 kfree_sensitive(tls_psk); 609 out_free_digest: 610 kfree_sensitive(digest); 611 out_free_psk: 612 kfree_sensitive(psk); 613 } 614