Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvme-auth: use transformed key size to create resp

This does not change current behaviour as the driver currently
verifies that the secret size is the same size as the length of
the transformation hash.

Co-developed-by: Akash Appaiah <Akash.Appaiah@dell.com>
Signed-off-by: Akash Appaiah <Akash.Appaiah@dell.com>
Signed-off-by: Mark O'Donovan <shiftee@posteo.net>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Mark O'Donovan and committed by
Keith Busch
f047daed 3ebed374

+48 -39
+14 -9
drivers/nvme/common/auth.c
··· 242 242 } 243 243 EXPORT_SYMBOL_GPL(nvme_auth_free_key); 244 244 245 - u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn) 245 + struct nvme_dhchap_key *nvme_auth_transform_key( 246 + struct nvme_dhchap_key *key, char *nqn) 246 247 { 247 248 const char *hmac_name; 248 249 struct crypto_shash *key_tfm; 249 250 struct shash_desc *shash; 250 - u8 *transformed_key; 251 - int ret; 251 + struct nvme_dhchap_key *transformed_key; 252 + int ret, key_len; 252 253 253 254 if (!key) { 254 255 pr_warn("No key specified\n"); 255 256 return ERR_PTR(-ENOKEY); 256 257 } 257 258 if (key->hash == 0) { 258 - transformed_key = kmemdup(key->key, key->len, GFP_KERNEL); 259 - return transformed_key ? transformed_key : ERR_PTR(-ENOMEM); 259 + key_len = nvme_auth_key_struct_size(key->len); 260 + transformed_key = kmemdup(key, key_len, GFP_KERNEL); 261 + if (!transformed_key) 262 + return ERR_PTR(-ENOMEM); 263 + return transformed_key; 260 264 } 261 265 hmac_name = nvme_auth_hmac_name(key->hash); 262 266 if (!hmac_name) { ··· 270 266 271 267 key_tfm = crypto_alloc_shash(hmac_name, 0, 0); 272 268 if (IS_ERR(key_tfm)) 273 - return (u8 *)key_tfm; 269 + return ERR_CAST(key_tfm); 274 270 275 271 shash = kmalloc(sizeof(struct shash_desc) + 276 272 crypto_shash_descsize(key_tfm), ··· 280 276 goto out_free_key; 281 277 } 282 278 283 - transformed_key = kzalloc(crypto_shash_digestsize(key_tfm), GFP_KERNEL); 279 + key_len = crypto_shash_digestsize(key_tfm); 280 + transformed_key = nvme_auth_alloc_key(key_len, key->hash); 284 281 if (!transformed_key) { 285 282 ret = -ENOMEM; 286 283 goto out_free_shash; ··· 300 295 ret = crypto_shash_update(shash, "NVMe-over-Fabrics", 17); 301 296 if (ret < 0) 302 297 goto out_free_transformed_key; 303 - ret = crypto_shash_final(shash, transformed_key); 298 + ret = crypto_shash_final(shash, transformed_key->key); 304 299 if (ret < 0) 305 300 goto out_free_transformed_key; 306 301 ··· 310 305 return transformed_key; 311 306 312 307 out_free_transformed_key: 313 - kfree_sensitive(transformed_key); 308 + nvme_auth_free_key(transformed_key); 314 309 out_free_shash: 315 310 kfree(shash); 316 311 out_free_key:
+15 -15
drivers/nvme/host/auth.c
··· 23 23 struct nvme_ctrl *ctrl; 24 24 struct crypto_shash *shash_tfm; 25 25 struct crypto_kpp *dh_tfm; 26 + struct nvme_dhchap_key *transformed_key; 26 27 void *buf; 27 28 int qid; 28 29 int error; ··· 37 36 u8 c1[64]; 38 37 u8 c2[64]; 39 38 u8 response[64]; 40 - u8 *host_response; 41 39 u8 *ctrl_key; 42 40 u8 *host_key; 43 41 u8 *sess_key; ··· 428 428 dev_dbg(ctrl->device, "%s: qid %d host response seq %u transaction %d\n", 429 429 __func__, chap->qid, chap->s1, chap->transaction); 430 430 431 - if (!chap->host_response) { 432 - chap->host_response = nvme_auth_transform_key(ctrl->host_key, 431 + if (!chap->transformed_key) { 432 + chap->transformed_key = nvme_auth_transform_key(ctrl->host_key, 433 433 ctrl->opts->host->nqn); 434 - if (IS_ERR(chap->host_response)) { 435 - ret = PTR_ERR(chap->host_response); 436 - chap->host_response = NULL; 434 + if (IS_ERR(chap->transformed_key)) { 435 + ret = PTR_ERR(chap->transformed_key); 436 + chap->transformed_key = NULL; 437 437 return ret; 438 438 } 439 439 } else { ··· 442 442 } 443 443 444 444 ret = crypto_shash_setkey(chap->shash_tfm, 445 - chap->host_response, ctrl->host_key->len); 445 + chap->transformed_key->key, chap->transformed_key->len); 446 446 if (ret) { 447 447 dev_warn(ctrl->device, "qid %d: failed to set key, error %d\n", 448 448 chap->qid, ret); ··· 508 508 struct nvme_dhchap_queue_context *chap) 509 509 { 510 510 SHASH_DESC_ON_STACK(shash, chap->shash_tfm); 511 - u8 *ctrl_response; 511 + struct nvme_dhchap_key *transformed_key; 512 512 u8 buf[4], *challenge = chap->c2; 513 513 int ret; 514 514 515 - ctrl_response = nvme_auth_transform_key(ctrl->ctrl_key, 515 + transformed_key = nvme_auth_transform_key(ctrl->ctrl_key, 516 516 ctrl->opts->subsysnqn); 517 - if (IS_ERR(ctrl_response)) { 518 - ret = PTR_ERR(ctrl_response); 517 + if (IS_ERR(transformed_key)) { 518 + ret = PTR_ERR(transformed_key); 519 519 return ret; 520 520 } 521 521 522 522 ret = crypto_shash_setkey(chap->shash_tfm, 523 - ctrl_response, ctrl->ctrl_key->len); 523 + transformed_key->key, transformed_key->len); 524 524 if (ret) { 525 525 dev_warn(ctrl->device, "qid %d: failed to set key, error %d\n", 526 526 chap->qid, ret); ··· 586 586 out: 587 587 if (challenge != chap->c2) 588 588 kfree(challenge); 589 - kfree(ctrl_response); 589 + nvme_auth_free_key(transformed_key); 590 590 return ret; 591 591 } 592 592 ··· 648 648 649 649 static void nvme_auth_reset_dhchap(struct nvme_dhchap_queue_context *chap) 650 650 { 651 - kfree_sensitive(chap->host_response); 652 - chap->host_response = NULL; 651 + nvme_auth_free_key(chap->transformed_key); 652 + chap->transformed_key = NULL; 653 653 kfree_sensitive(chap->host_key); 654 654 chap->host_key = NULL; 655 655 chap->host_key_len = 0;
+17 -14
drivers/nvme/target/auth.c
··· 267 267 struct shash_desc *shash; 268 268 struct nvmet_ctrl *ctrl = req->sq->ctrl; 269 269 const char *hash_name; 270 - u8 *challenge = req->sq->dhchap_c1, *host_response; 270 + u8 *challenge = req->sq->dhchap_c1; 271 + struct nvme_dhchap_key *transformed_key; 271 272 u8 buf[4]; 272 273 int ret; 273 274 ··· 292 291 goto out_free_tfm; 293 292 } 294 293 295 - host_response = nvme_auth_transform_key(ctrl->host_key, ctrl->hostnqn); 296 - if (IS_ERR(host_response)) { 297 - ret = PTR_ERR(host_response); 294 + transformed_key = nvme_auth_transform_key(ctrl->host_key, 295 + ctrl->hostnqn); 296 + if (IS_ERR(transformed_key)) { 297 + ret = PTR_ERR(transformed_key); 298 298 goto out_free_tfm; 299 299 } 300 300 301 - ret = crypto_shash_setkey(shash_tfm, host_response, 302 - ctrl->host_key->len); 301 + ret = crypto_shash_setkey(shash_tfm, transformed_key->key, 302 + transformed_key->len); 303 303 if (ret) 304 304 goto out_free_response; 305 305 ··· 367 365 kfree(challenge); 368 366 kfree(shash); 369 367 out_free_response: 370 - kfree_sensitive(host_response); 368 + nvme_auth_free_key(transformed_key); 371 369 out_free_tfm: 372 370 crypto_free_shash(shash_tfm); 373 371 return 0; ··· 380 378 struct shash_desc *shash; 381 379 struct nvmet_ctrl *ctrl = req->sq->ctrl; 382 380 const char *hash_name; 383 - u8 *challenge = req->sq->dhchap_c2, *ctrl_response; 381 + u8 *challenge = req->sq->dhchap_c2; 382 + struct nvme_dhchap_key *transformed_key; 384 383 u8 buf[4]; 385 384 int ret; 386 385 ··· 405 402 goto out_free_tfm; 406 403 } 407 404 408 - ctrl_response = nvme_auth_transform_key(ctrl->ctrl_key, 405 + transformed_key = nvme_auth_transform_key(ctrl->ctrl_key, 409 406 ctrl->subsysnqn); 410 - if (IS_ERR(ctrl_response)) { 411 - ret = PTR_ERR(ctrl_response); 407 + if (IS_ERR(transformed_key)) { 408 + ret = PTR_ERR(transformed_key); 412 409 goto out_free_tfm; 413 410 } 414 411 415 - ret = crypto_shash_setkey(shash_tfm, ctrl_response, 416 - ctrl->ctrl_key->len); 412 + ret = crypto_shash_setkey(shash_tfm, transformed_key->key, 413 + transformed_key->len); 417 414 if (ret) 418 415 goto out_free_response; 419 416 ··· 477 474 kfree(challenge); 478 475 kfree(shash); 479 476 out_free_response: 480 - kfree_sensitive(ctrl_response); 477 + nvme_auth_free_key(transformed_key); 481 478 out_free_tfm: 482 479 crypto_free_shash(shash_tfm); 483 480 return 0;
+2 -1
include/linux/nvme-auth.h
··· 29 29 u8 key_hash); 30 30 void nvme_auth_free_key(struct nvme_dhchap_key *key); 31 31 struct nvme_dhchap_key *nvme_auth_alloc_key(u32 len, u8 hash); 32 - u8 *nvme_auth_transform_key(struct nvme_dhchap_key *key, char *nqn); 32 + struct nvme_dhchap_key *nvme_auth_transform_key( 33 + struct nvme_dhchap_key *key, char *nqn); 33 34 int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key); 34 35 int nvme_auth_augmented_challenge(u8 hmac_id, u8 *skey, size_t skey_len, 35 36 u8 *challenge, u8 *aug, size_t hlen);