1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2019 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/opal.h" 7 #include "spdk/log.h" 8 #include "spdk/util.h" 9 10 #include "nvme_opal_internal.h" 11 12 static void 13 opal_nvme_security_recv_done(void *arg, const struct spdk_nvme_cpl *cpl) 14 { 15 struct opal_session *sess = arg; 16 struct spdk_opal_dev *dev = sess->dev; 17 void *response = sess->resp; 18 struct spdk_opal_compacket *header = response; 19 int ret; 20 21 if (spdk_nvme_cpl_is_error(cpl)) { 22 sess->sess_cb(sess, -EIO, sess->cb_arg); 23 return; 24 } 25 26 if (!header->outstanding_data && !header->min_transfer) { 27 sess->sess_cb(sess, 0, sess->cb_arg); 28 return; 29 } 30 31 memset(response, 0, IO_BUFFER_LENGTH); 32 ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG, 33 dev->comid, 0, sess->resp, IO_BUFFER_LENGTH, 34 opal_nvme_security_recv_done, sess); 35 if (ret) { 36 sess->sess_cb(sess, ret, sess->cb_arg); 37 } 38 } 39 40 static void 41 opal_nvme_security_send_done(void *arg, const struct spdk_nvme_cpl *cpl) 42 { 43 struct opal_session *sess = arg; 44 struct spdk_opal_dev *dev = sess->dev; 45 int ret; 46 47 if (spdk_nvme_cpl_is_error(cpl)) { 48 sess->sess_cb(sess, -EIO, sess->cb_arg); 49 return; 50 } 51 52 ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG, 53 dev->comid, 0, sess->resp, IO_BUFFER_LENGTH, 54 opal_nvme_security_recv_done, sess); 55 if (ret) { 56 sess->sess_cb(sess, ret, sess->cb_arg); 57 } 58 } 59 60 static int 61 opal_nvme_security_send(struct spdk_opal_dev *dev, struct opal_session *sess, 62 opal_sess_cb sess_cb, void *cb_arg) 63 { 64 sess->sess_cb = sess_cb; 65 sess->cb_arg = cb_arg; 66 67 return spdk_nvme_ctrlr_cmd_security_send(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid, 68 0, sess->cmd, IO_BUFFER_LENGTH, 69 opal_nvme_security_send_done, sess); 70 } 71 72 static void 73 opal_send_recv_done(struct opal_session *sess, int status, void *ctx) 74 { 75 sess->status = status; 76 sess->done = true; 77 } 78 79 static int 80 opal_send_recv(struct spdk_opal_dev *dev, struct opal_session *sess) 81 { 82 int ret; 83 84 sess->done = false; 85 ret = opal_nvme_security_send(dev, sess, opal_send_recv_done, NULL); 86 if (ret) { 87 return ret; 88 } 89 90 while (!sess->done) { 91 spdk_nvme_ctrlr_process_admin_completions(dev->ctrlr); 92 } 93 94 return sess->status; 95 } 96 97 static struct opal_session * 98 opal_alloc_session(struct spdk_opal_dev *dev) 99 { 100 struct opal_session *sess; 101 102 sess = calloc(1, sizeof(*sess)); 103 if (!sess) { 104 return NULL; 105 } 106 sess->dev = dev; 107 108 return sess; 109 } 110 111 static void 112 opal_add_token_u8(int *err, struct opal_session *sess, uint8_t token) 113 { 114 if (*err) { 115 return; 116 } 117 if (sess->cmd_pos >= IO_BUFFER_LENGTH - 1) { 118 SPDK_ERRLOG("Error adding u8: end of buffer.\n"); 119 *err = -ERANGE; 120 return; 121 } 122 sess->cmd[sess->cmd_pos++] = token; 123 } 124 125 static void 126 opal_add_short_atom_header(struct opal_session *sess, bool bytestring, 127 bool has_sign, size_t len) 128 { 129 uint8_t atom; 130 int err = 0; 131 132 atom = SPDK_SHORT_ATOM_ID; 133 atom |= bytestring ? SPDK_SHORT_ATOM_BYTESTRING_FLAG : 0; 134 atom |= has_sign ? SPDK_SHORT_ATOM_SIGN_FLAG : 0; 135 atom |= len & SPDK_SHORT_ATOM_LEN_MASK; 136 137 opal_add_token_u8(&err, sess, atom); 138 } 139 140 static void 141 opal_add_medium_atom_header(struct opal_session *sess, bool bytestring, 142 bool has_sign, size_t len) 143 { 144 uint8_t header; 145 146 header = SPDK_MEDIUM_ATOM_ID; 147 header |= bytestring ? SPDK_MEDIUM_ATOM_BYTESTRING_FLAG : 0; 148 header |= has_sign ? SPDK_MEDIUM_ATOM_SIGN_FLAG : 0; 149 header |= (len >> 8) & SPDK_MEDIUM_ATOM_LEN_MASK; 150 sess->cmd[sess->cmd_pos++] = header; 151 sess->cmd[sess->cmd_pos++] = len; 152 } 153 154 static void 155 opal_add_token_bytestring(int *err, struct opal_session *sess, 156 const uint8_t *bytestring, size_t len) 157 { 158 size_t header_len = 1; 159 bool is_short_atom = true; 160 161 if (*err) { 162 return; 163 } 164 165 if (len & ~SPDK_SHORT_ATOM_LEN_MASK) { 166 header_len = 2; 167 is_short_atom = false; 168 } 169 170 if (len >= IO_BUFFER_LENGTH - sess->cmd_pos - header_len) { 171 SPDK_ERRLOG("Error adding bytestring: end of buffer.\n"); 172 *err = -ERANGE; 173 return; 174 } 175 176 if (is_short_atom) { 177 opal_add_short_atom_header(sess, true, false, len); 178 } else { 179 opal_add_medium_atom_header(sess, true, false, len); 180 } 181 182 memcpy(&sess->cmd[sess->cmd_pos], bytestring, len); 183 sess->cmd_pos += len; 184 } 185 186 static void 187 opal_add_token_u64(int *err, struct opal_session *sess, uint64_t number) 188 { 189 int startat = 0; 190 191 if (*err) { 192 return; 193 } 194 195 /* add header first */ 196 if (number <= SPDK_TINY_ATOM_DATA_MASK) { 197 sess->cmd[sess->cmd_pos++] = (uint8_t) number & SPDK_TINY_ATOM_DATA_MASK; 198 } else { 199 if (number < 0x100) { 200 sess->cmd[sess->cmd_pos++] = 0x81; /* short atom, 1 byte length */ 201 startat = 0; 202 } else if (number < 0x10000) { 203 sess->cmd[sess->cmd_pos++] = 0x82; /* short atom, 2 byte length */ 204 startat = 1; 205 } else if (number < 0x100000000) { 206 sess->cmd[sess->cmd_pos++] = 0x84; /* short atom, 4 byte length */ 207 startat = 3; 208 } else { 209 sess->cmd[sess->cmd_pos++] = 0x88; /* short atom, 8 byte length */ 210 startat = 7; 211 } 212 213 /* add number value */ 214 for (int i = startat; i > -1; i--) { 215 sess->cmd[sess->cmd_pos++] = (uint8_t)((number >> (i * 8)) & 0xff); 216 } 217 } 218 } 219 220 static void 221 opal_add_tokens(int *err, struct opal_session *sess, int num, ...) 222 { 223 int i; 224 va_list args_ptr; 225 enum spdk_opal_token tmp; 226 227 va_start(args_ptr, num); 228 229 for (i = 0; i < num; i++) { 230 tmp = va_arg(args_ptr, enum spdk_opal_token); 231 opal_add_token_u8(err, sess, tmp); 232 if (*err != 0) { break; } 233 } 234 235 va_end(args_ptr); 236 } 237 238 static int 239 opal_cmd_finalize(struct opal_session *sess, uint32_t hsn, uint32_t tsn, bool eod) 240 { 241 struct spdk_opal_header *hdr; 242 int err = 0; 243 244 if (eod) { 245 opal_add_tokens(&err, sess, 6, SPDK_OPAL_ENDOFDATA, 246 SPDK_OPAL_STARTLIST, 247 0, 0, 0, 248 SPDK_OPAL_ENDLIST); 249 } 250 251 if (err) { 252 SPDK_ERRLOG("Error finalizing command.\n"); 253 return -EFAULT; 254 } 255 256 hdr = (struct spdk_opal_header *)sess->cmd; 257 258 to_be32(&hdr->packet.session_tsn, tsn); 259 to_be32(&hdr->packet.session_hsn, hsn); 260 261 to_be32(&hdr->sub_packet.length, sess->cmd_pos - sizeof(*hdr)); 262 while (sess->cmd_pos % 4) { 263 if (sess->cmd_pos >= IO_BUFFER_LENGTH) { 264 SPDK_ERRLOG("Error: Buffer overrun\n"); 265 return -ERANGE; 266 } 267 sess->cmd[sess->cmd_pos++] = 0; 268 } 269 to_be32(&hdr->packet.length, sess->cmd_pos - sizeof(hdr->com_packet) - 270 sizeof(hdr->packet)); 271 to_be32(&hdr->com_packet.length, sess->cmd_pos - sizeof(hdr->com_packet)); 272 273 return 0; 274 } 275 276 static size_t 277 opal_response_parse_tiny(struct spdk_opal_resp_token *token, 278 const uint8_t *pos) 279 { 280 token->pos = pos; 281 token->len = 1; 282 token->width = OPAL_WIDTH_TINY; 283 284 if (pos[0] & SPDK_TINY_ATOM_SIGN_FLAG) { 285 token->type = OPAL_DTA_TOKENID_SINT; 286 } else { 287 token->type = OPAL_DTA_TOKENID_UINT; 288 token->stored.unsigned_num = pos[0] & SPDK_TINY_ATOM_DATA_MASK; 289 } 290 291 return token->len; 292 } 293 294 static int 295 opal_response_parse_short(struct spdk_opal_resp_token *token, 296 const uint8_t *pos) 297 { 298 token->pos = pos; 299 token->len = (pos[0] & SPDK_SHORT_ATOM_LEN_MASK) + 1; /* plus 1-byte header */ 300 token->width = OPAL_WIDTH_SHORT; 301 302 if (pos[0] & SPDK_SHORT_ATOM_BYTESTRING_FLAG) { 303 token->type = OPAL_DTA_TOKENID_BYTESTRING; 304 } else if (pos[0] & SPDK_SHORT_ATOM_SIGN_FLAG) { 305 token->type = OPAL_DTA_TOKENID_SINT; 306 } else { 307 uint64_t u_integer = 0; 308 size_t i, b = 0; 309 310 token->type = OPAL_DTA_TOKENID_UINT; 311 if (token->len > 9) { 312 SPDK_ERRLOG("uint64 with more than 8 bytes\n"); 313 return -EINVAL; 314 } 315 for (i = token->len - 1; i > 0; i--) { 316 u_integer |= ((uint64_t)pos[i] << (8 * b)); 317 b++; 318 } 319 token->stored.unsigned_num = u_integer; 320 } 321 322 return token->len; 323 } 324 325 static size_t 326 opal_response_parse_medium(struct spdk_opal_resp_token *token, 327 const uint8_t *pos) 328 { 329 token->pos = pos; 330 token->len = (((pos[0] & SPDK_MEDIUM_ATOM_LEN_MASK) << 8) | pos[1]) + 2; /* plus 2-byte header */ 331 token->width = OPAL_WIDTH_MEDIUM; 332 333 if (pos[0] & SPDK_MEDIUM_ATOM_BYTESTRING_FLAG) { 334 token->type = OPAL_DTA_TOKENID_BYTESTRING; 335 } else if (pos[0] & SPDK_MEDIUM_ATOM_SIGN_FLAG) { 336 token->type = OPAL_DTA_TOKENID_SINT; 337 } else { 338 token->type = OPAL_DTA_TOKENID_UINT; 339 } 340 341 return token->len; 342 } 343 344 static size_t 345 opal_response_parse_long(struct spdk_opal_resp_token *token, 346 const uint8_t *pos) 347 { 348 token->pos = pos; 349 token->len = ((pos[1] << 16) | (pos[2] << 8) | pos[3]) + 4; /* plus 4-byte header */ 350 token->width = OPAL_WIDTH_LONG; 351 352 if (pos[0] & SPDK_LONG_ATOM_BYTESTRING_FLAG) { 353 token->type = OPAL_DTA_TOKENID_BYTESTRING; 354 } else if (pos[0] & SPDK_LONG_ATOM_SIGN_FLAG) { 355 token->type = OPAL_DTA_TOKENID_SINT; 356 } else { 357 token->type = OPAL_DTA_TOKENID_UINT; 358 } 359 360 return token->len; 361 } 362 363 static size_t 364 opal_response_parse_token(struct spdk_opal_resp_token *token, 365 const uint8_t *pos) 366 { 367 token->pos = pos; 368 token->len = 1; 369 token->type = OPAL_DTA_TOKENID_TOKEN; 370 token->width = OPAL_WIDTH_TOKEN; 371 372 return token->len; 373 } 374 375 static int 376 opal_response_parse(const uint8_t *buf, size_t length, 377 struct spdk_opal_resp_parsed *resp) 378 { 379 const struct spdk_opal_header *hdr; 380 struct spdk_opal_resp_token *token_iter; 381 int num_entries = 0; 382 int total; 383 size_t token_length; 384 const uint8_t *pos; 385 uint32_t clen, plen, slen; 386 387 if (!buf || !resp) { 388 return -EINVAL; 389 } 390 391 hdr = (struct spdk_opal_header *)buf; 392 pos = buf + sizeof(*hdr); 393 394 clen = from_be32(&hdr->com_packet.length); 395 plen = from_be32(&hdr->packet.length); 396 slen = from_be32(&hdr->sub_packet.length); 397 SPDK_DEBUGLOG(opal, "Response size: cp: %u, pkt: %u, subpkt: %u\n", 398 clen, plen, slen); 399 400 if (clen == 0 || plen == 0 || slen == 0 || 401 slen > IO_BUFFER_LENGTH - sizeof(*hdr)) { 402 SPDK_ERRLOG("Bad header length. cp: %u, pkt: %u, subpkt: %u\n", 403 clen, plen, slen); 404 return -EINVAL; 405 } 406 407 if (pos > buf + length) { 408 SPDK_ERRLOG("Pointer out of range\n"); 409 return -EFAULT; 410 } 411 412 token_iter = resp->resp_tokens; 413 total = slen; 414 415 while (total > 0) { 416 if (pos[0] <= SPDK_TINY_ATOM_TYPE_MAX) { /* tiny atom */ 417 token_length = opal_response_parse_tiny(token_iter, pos); 418 } else if (pos[0] <= SPDK_SHORT_ATOM_TYPE_MAX) { /* short atom */ 419 token_length = opal_response_parse_short(token_iter, pos); 420 } else if (pos[0] <= SPDK_MEDIUM_ATOM_TYPE_MAX) { /* medium atom */ 421 token_length = opal_response_parse_medium(token_iter, pos); 422 } else if (pos[0] <= SPDK_LONG_ATOM_TYPE_MAX) { /* long atom */ 423 token_length = opal_response_parse_long(token_iter, pos); 424 } else { /* TOKEN */ 425 token_length = opal_response_parse_token(token_iter, pos); 426 } 427 428 if (token_length <= 0) { 429 SPDK_ERRLOG("Parse response failure.\n"); 430 return -EINVAL; 431 } 432 433 pos += token_length; 434 total -= token_length; 435 token_iter++; 436 num_entries++; 437 438 if (total < 0) { 439 SPDK_ERRLOG("Length not matching.\n"); 440 return -EINVAL; 441 } 442 } 443 444 if (num_entries == 0) { 445 SPDK_ERRLOG("Couldn't parse response.\n"); 446 return -EINVAL; 447 } 448 resp->num = num_entries; 449 450 return 0; 451 } 452 453 static inline bool 454 opal_response_token_matches(const struct spdk_opal_resp_token *token, 455 uint8_t match) 456 { 457 if (!token || 458 token->type != OPAL_DTA_TOKENID_TOKEN || 459 token->pos[0] != match) { 460 return false; 461 } 462 return true; 463 } 464 465 static const struct spdk_opal_resp_token * 466 opal_response_get_token(const struct spdk_opal_resp_parsed *resp, int index) 467 { 468 const struct spdk_opal_resp_token *token; 469 470 if (index >= resp->num) { 471 SPDK_ERRLOG("Token number doesn't exist: %d, resp: %d\n", 472 index, resp->num); 473 return NULL; 474 } 475 476 token = &resp->resp_tokens[index]; 477 if (token->len == 0) { 478 SPDK_ERRLOG("Token length must be non-zero\n"); 479 return NULL; 480 } 481 482 return token; 483 } 484 485 static uint64_t 486 opal_response_get_u64(const struct spdk_opal_resp_parsed *resp, int index) 487 { 488 if (!resp) { 489 SPDK_ERRLOG("Response is NULL\n"); 490 return 0; 491 } 492 493 if (resp->resp_tokens[index].type != OPAL_DTA_TOKENID_UINT) { 494 SPDK_ERRLOG("Token is not unsigned int: %d\n", 495 resp->resp_tokens[index].type); 496 return 0; 497 } 498 499 if (!(resp->resp_tokens[index].width == OPAL_WIDTH_TINY || 500 resp->resp_tokens[index].width == OPAL_WIDTH_SHORT)) { 501 SPDK_ERRLOG("Atom is not short or tiny: %d\n", 502 resp->resp_tokens[index].width); 503 return 0; 504 } 505 506 return resp->resp_tokens[index].stored.unsigned_num; 507 } 508 509 static uint16_t 510 opal_response_get_u16(const struct spdk_opal_resp_parsed *resp, int index) 511 { 512 uint64_t i = opal_response_get_u64(resp, index); 513 if (i > 0xffffull) { 514 SPDK_ERRLOG("parse response u16 failed. Overflow\n"); 515 return 0; 516 } 517 return (uint16_t) i; 518 } 519 520 static uint8_t 521 opal_response_get_u8(const struct spdk_opal_resp_parsed *resp, int index) 522 { 523 uint64_t i = opal_response_get_u64(resp, index); 524 if (i > 0xffull) { 525 SPDK_ERRLOG("parse response u8 failed. Overflow\n"); 526 return 0; 527 } 528 return (uint8_t) i; 529 } 530 531 static size_t 532 opal_response_get_string(const struct spdk_opal_resp_parsed *resp, int n, 533 const char **store) 534 { 535 uint8_t header_len; 536 struct spdk_opal_resp_token token; 537 *store = NULL; 538 if (!resp) { 539 SPDK_ERRLOG("Response is NULL\n"); 540 return 0; 541 } 542 543 if (n > resp->num) { 544 SPDK_ERRLOG("Response has %d tokens. Can't access %d\n", 545 resp->num, n); 546 return 0; 547 } 548 549 token = resp->resp_tokens[n]; 550 if (token.type != OPAL_DTA_TOKENID_BYTESTRING) { 551 SPDK_ERRLOG("Token is not a byte string!\n"); 552 return 0; 553 } 554 555 switch (token.width) { 556 case OPAL_WIDTH_SHORT: 557 header_len = 1; 558 break; 559 case OPAL_WIDTH_MEDIUM: 560 header_len = 2; 561 break; 562 case OPAL_WIDTH_LONG: 563 header_len = 4; 564 break; 565 default: 566 SPDK_ERRLOG("Can't get string from this Token\n"); 567 return 0; 568 } 569 570 *store = token.pos + header_len; 571 return token.len - header_len; 572 } 573 574 static int 575 opal_response_status(const struct spdk_opal_resp_parsed *resp) 576 { 577 const struct spdk_opal_resp_token *tok; 578 579 /* if we get an EOS token, just return 0 */ 580 tok = opal_response_get_token(resp, 0); 581 if (opal_response_token_matches(tok, SPDK_OPAL_ENDOFSESSION)) { 582 return 0; 583 } 584 585 if (resp->num < 5) { 586 return SPDK_DTAERROR_NO_METHOD_STATUS; 587 } 588 589 tok = opal_response_get_token(resp, resp->num - 5); /* the first token should be STARTLIST */ 590 if (!opal_response_token_matches(tok, SPDK_OPAL_STARTLIST)) { 591 return SPDK_DTAERROR_NO_METHOD_STATUS; 592 } 593 594 tok = opal_response_get_token(resp, resp->num - 1); /* the last token should be ENDLIST */ 595 if (!opal_response_token_matches(tok, SPDK_OPAL_ENDLIST)) { 596 return SPDK_DTAERROR_NO_METHOD_STATUS; 597 } 598 599 /* The second and third values in the status list are reserved, and are 600 defined in core spec to be 0x00 and 0x00 and SHOULD be ignored by the host. */ 601 return (int)opal_response_get_u64(resp, 602 resp->num - 4); /* We only need the first value in the status list. */ 603 } 604 605 static int 606 opal_parse_and_check_status(struct opal_session *sess) 607 { 608 int error; 609 610 error = opal_response_parse(sess->resp, IO_BUFFER_LENGTH, &sess->parsed_resp); 611 if (error) { 612 SPDK_ERRLOG("Couldn't parse response.\n"); 613 return error; 614 } 615 return opal_response_status(&sess->parsed_resp); 616 } 617 618 static inline void 619 opal_clear_cmd(struct opal_session *sess) 620 { 621 sess->cmd_pos = sizeof(struct spdk_opal_header); 622 memset(sess->cmd, 0, IO_BUFFER_LENGTH); 623 } 624 625 static inline void 626 opal_set_comid(struct opal_session *sess, uint16_t comid) 627 { 628 struct spdk_opal_header *hdr = (struct spdk_opal_header *)sess->cmd; 629 630 hdr->com_packet.comid[0] = comid >> 8; 631 hdr->com_packet.comid[1] = comid; 632 hdr->com_packet.extended_comid[0] = 0; 633 hdr->com_packet.extended_comid[1] = 0; 634 } 635 636 static inline int 637 opal_init_key(struct spdk_opal_key *opal_key, const char *passwd) 638 { 639 int len; 640 641 if (passwd == NULL || passwd[0] == '\0') { 642 SPDK_ERRLOG("Password is empty. Create key failed\n"); 643 return -EINVAL; 644 } 645 646 len = strlen(passwd); 647 648 if (len >= OPAL_KEY_MAX) { 649 SPDK_ERRLOG("Password too long. Create key failed\n"); 650 return -EINVAL; 651 } 652 653 opal_key->key_len = len; 654 memcpy(opal_key->key, passwd, opal_key->key_len); 655 656 return 0; 657 } 658 659 static void 660 opal_build_locking_range(uint8_t *buffer, uint8_t locking_range) 661 { 662 memcpy(buffer, spdk_opal_uid[UID_LOCKINGRANGE_GLOBAL], OPAL_UID_LENGTH); 663 664 /* global */ 665 if (locking_range == 0) { 666 return; 667 } 668 669 /* non-global */ 670 buffer[5] = LOCKING_RANGE_NON_GLOBAL; 671 buffer[7] = locking_range; 672 } 673 674 static void 675 opal_check_tper(struct spdk_opal_dev *dev, const void *data) 676 { 677 const struct spdk_opal_d0_tper_feat *tper = data; 678 679 dev->feat_info.tper = *tper; 680 } 681 682 /* 683 * check single user mode 684 */ 685 static bool 686 opal_check_sum(struct spdk_opal_dev *dev, const void *data) 687 { 688 const struct spdk_opal_d0_single_user_mode_feat *sum = data; 689 uint32_t num_locking_objects = from_be32(&sum->num_locking_objects); 690 691 if (num_locking_objects == 0) { 692 SPDK_NOTICELOG("Need at least one locking object.\n"); 693 return false; 694 } 695 696 dev->feat_info.single_user = *sum; 697 698 return true; 699 } 700 701 static void 702 opal_check_lock(struct spdk_opal_dev *dev, const void *data) 703 { 704 const struct spdk_opal_d0_locking_feat *lock = data; 705 706 dev->feat_info.locking = *lock; 707 } 708 709 static void 710 opal_check_geometry(struct spdk_opal_dev *dev, const void *data) 711 { 712 const struct spdk_opal_d0_geo_feat *geo = data; 713 714 dev->feat_info.geo = *geo; 715 } 716 717 static void 718 opal_check_datastore(struct spdk_opal_dev *dev, const void *data) 719 { 720 const struct spdk_opal_d0_datastore_feat *datastore = data; 721 722 dev->feat_info.datastore = *datastore; 723 } 724 725 static uint16_t 726 opal_get_comid_v100(struct spdk_opal_dev *dev, const void *data) 727 { 728 const struct spdk_opal_d0_v100_feat *v100 = data; 729 uint16_t base_comid = from_be16(&v100->base_comid); 730 731 dev->feat_info.v100 = *v100; 732 733 return base_comid; 734 } 735 736 static uint16_t 737 opal_get_comid_v200(struct spdk_opal_dev *dev, const void *data) 738 { 739 const struct spdk_opal_d0_v200_feat *v200 = data; 740 uint16_t base_comid = from_be16(&v200->base_comid); 741 742 dev->feat_info.v200 = *v200; 743 744 return base_comid; 745 } 746 747 static int 748 opal_discovery0_end(struct spdk_opal_dev *dev, void *payload, uint32_t payload_size) 749 { 750 bool supported = false, single_user = false; 751 const struct spdk_opal_d0_hdr *hdr = (struct spdk_opal_d0_hdr *)payload; 752 struct spdk_opal_d0_feat_hdr *feat_hdr; 753 const uint8_t *epos = payload, *cpos = payload; 754 uint16_t comid = 0; 755 uint32_t hlen = from_be32(&(hdr->length)); 756 757 if (hlen > payload_size - sizeof(*hdr)) { 758 SPDK_ERRLOG("Discovery length overflows buffer (%zu+%u)/%u\n", 759 sizeof(*hdr), hlen, payload_size); 760 return -EFAULT; 761 } 762 763 epos += hlen; /* end of buffer */ 764 cpos += sizeof(*hdr); /* current position on buffer */ 765 766 while (cpos < epos) { 767 feat_hdr = (struct spdk_opal_d0_feat_hdr *)cpos; 768 uint16_t feat_code = from_be16(&feat_hdr->code); 769 770 switch (feat_code) { 771 case FEATURECODE_TPER: 772 opal_check_tper(dev, cpos); 773 break; 774 case FEATURECODE_SINGLEUSER: 775 single_user = opal_check_sum(dev, cpos); 776 break; 777 case FEATURECODE_GEOMETRY: 778 opal_check_geometry(dev, cpos); 779 break; 780 case FEATURECODE_LOCKING: 781 opal_check_lock(dev, cpos); 782 break; 783 case FEATURECODE_DATASTORE: 784 opal_check_datastore(dev, cpos); 785 break; 786 case FEATURECODE_OPALV100: 787 comid = opal_get_comid_v100(dev, cpos); 788 supported = true; 789 break; 790 case FEATURECODE_OPALV200: 791 comid = opal_get_comid_v200(dev, cpos); 792 supported = true; 793 break; 794 default: 795 SPDK_INFOLOG(opal, "Unknown feature code: %d\n", feat_code); 796 } 797 cpos += feat_hdr->length + sizeof(*feat_hdr); 798 } 799 800 if (supported == false) { 801 SPDK_INFOLOG(opal, "Opal Not Supported.\n"); 802 return -ENOTSUP; 803 } 804 805 if (single_user == false) { 806 SPDK_INFOLOG(opal, "Single User Mode Not Supported\n"); 807 } 808 809 dev->comid = comid; 810 return 0; 811 } 812 813 static int 814 opal_discovery0(struct spdk_opal_dev *dev, void *payload, uint32_t payload_size) 815 { 816 int ret; 817 uint16_t i, sp_list_len; 818 uint8_t *sp_list; 819 bool sp_tcg_supported = false; 820 821 /* NVMe 1.4 chapter 5.25.2 Security Protocol 00h */ 822 ret = spdk_nvme_ctrlr_security_receive(dev->ctrlr, SPDK_SCSI_SECP_INFO, 0, 823 0, payload, payload_size); 824 if (ret) { 825 return ret; 826 } 827 828 /* spc4r31 chapter 7.7.1.3 Supported security protocols list description */ 829 sp_list_len = from_be16(payload + 6); 830 sp_list = (uint8_t *)payload + 8; 831 832 if (sp_list_len + 8 > (int)payload_size) { 833 return -EINVAL; 834 } 835 836 for (i = 0; i < sp_list_len; i++) { 837 if (sp_list[i] == SPDK_SCSI_SECP_TCG) { 838 sp_tcg_supported = true; 839 break; 840 } 841 } 842 843 if (!sp_tcg_supported) { 844 return -ENOTSUP; 845 } 846 847 memset(payload, 0, payload_size); 848 ret = spdk_nvme_ctrlr_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG, LV0_DISCOVERY_COMID, 849 0, payload, payload_size); 850 if (ret) { 851 return ret; 852 } 853 854 return opal_discovery0_end(dev, payload, payload_size); 855 } 856 857 static int 858 opal_end_session(struct spdk_opal_dev *dev, struct opal_session *sess, uint16_t comid) 859 { 860 int err = 0; 861 int ret; 862 863 opal_clear_cmd(sess); 864 opal_set_comid(sess, comid); 865 opal_add_token_u8(&err, sess, SPDK_OPAL_ENDOFSESSION); 866 867 if (err < 0) { 868 return err; 869 } 870 871 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, false); 872 if (ret) { 873 return ret; 874 } 875 876 ret = opal_send_recv(dev, sess); 877 if (ret) { 878 return ret; 879 } 880 881 sess->hsn = 0; 882 sess->tsn = 0; 883 884 return opal_parse_and_check_status(sess); 885 } 886 887 void 888 spdk_opal_dev_destruct(struct spdk_opal_dev *dev) 889 { 890 free(dev); 891 } 892 893 static int 894 opal_start_session_done(struct opal_session *sess) 895 { 896 uint32_t hsn, tsn; 897 int error = 0; 898 899 error = opal_parse_and_check_status(sess); 900 if (error) { 901 return error; 902 } 903 904 hsn = opal_response_get_u64(&sess->parsed_resp, 4); 905 tsn = opal_response_get_u64(&sess->parsed_resp, 5); 906 907 if (hsn == 0 && tsn == 0) { 908 SPDK_ERRLOG("Couldn't authenticate session\n"); 909 return -EPERM; 910 } 911 912 sess->hsn = hsn; 913 sess->tsn = tsn; 914 915 return 0; 916 } 917 918 static int 919 opal_start_generic_session(struct spdk_opal_dev *dev, 920 struct opal_session *sess, 921 enum opal_uid_enum auth, 922 enum opal_uid_enum sp_type, 923 const char *key, 924 uint8_t key_len) 925 { 926 uint32_t hsn; 927 int err = 0; 928 int ret; 929 930 if (key == NULL && auth != UID_ANYBODY) { 931 return OPAL_INVAL_PARAM; 932 } 933 934 opal_clear_cmd(sess); 935 936 opal_set_comid(sess, dev->comid); 937 hsn = GENERIC_HOST_SESSION_NUM; 938 939 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 940 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_SMUID], 941 OPAL_UID_LENGTH); 942 opal_add_token_bytestring(&err, sess, spdk_opal_method[STARTSESSION_METHOD], 943 OPAL_UID_LENGTH); 944 opal_add_token_u8(&err, sess, SPDK_OPAL_STARTLIST); 945 opal_add_token_u64(&err, sess, hsn); 946 opal_add_token_bytestring(&err, sess, spdk_opal_uid[sp_type], OPAL_UID_LENGTH); 947 opal_add_token_u8(&err, sess, SPDK_OPAL_TRUE); /* Write */ 948 949 switch (auth) { 950 case UID_ANYBODY: 951 opal_add_token_u8(&err, sess, SPDK_OPAL_ENDLIST); 952 break; 953 case UID_ADMIN1: 954 case UID_SID: 955 opal_add_token_u8(&err, sess, SPDK_OPAL_STARTNAME); 956 opal_add_token_u8(&err, sess, 0); /* HostChallenge */ 957 opal_add_token_bytestring(&err, sess, key, key_len); 958 opal_add_tokens(&err, sess, 3, /* number of token */ 959 SPDK_OPAL_ENDNAME, 960 SPDK_OPAL_STARTNAME, 961 3);/* HostSignAuth */ 962 opal_add_token_bytestring(&err, sess, spdk_opal_uid[auth], 963 OPAL_UID_LENGTH); 964 opal_add_token_u8(&err, sess, SPDK_OPAL_ENDNAME); 965 opal_add_token_u8(&err, sess, SPDK_OPAL_ENDLIST); 966 break; 967 default: 968 SPDK_ERRLOG("Cannot start Admin SP session with auth %d\n", auth); 969 return -EINVAL; 970 } 971 972 if (err) { 973 SPDK_ERRLOG("Error building start adminsp session command.\n"); 974 return err; 975 } 976 977 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 978 if (ret) { 979 return ret; 980 } 981 982 ret = opal_send_recv(dev, sess); 983 if (ret) { 984 return ret; 985 } 986 987 return opal_start_session_done(sess); 988 } 989 990 static int 991 opal_get_msid_cpin_pin_done(struct opal_session *sess, 992 struct spdk_opal_key *opal_key) 993 { 994 const char *msid_pin; 995 size_t strlen; 996 int error = 0; 997 998 error = opal_parse_and_check_status(sess); 999 if (error) { 1000 return error; 1001 } 1002 1003 strlen = opal_response_get_string(&sess->parsed_resp, 4, &msid_pin); 1004 if (!msid_pin) { 1005 SPDK_ERRLOG("Couldn't extract PIN from response\n"); 1006 return -EINVAL; 1007 } 1008 1009 opal_key->key_len = strlen; 1010 memcpy(opal_key->key, msid_pin, opal_key->key_len); 1011 1012 SPDK_DEBUGLOG(opal, "MSID = %p\n", opal_key->key); 1013 return 0; 1014 } 1015 1016 static int 1017 opal_get_msid_cpin_pin(struct spdk_opal_dev *dev, struct opal_session *sess, 1018 struct spdk_opal_key *opal_key) 1019 { 1020 int err = 0; 1021 int ret; 1022 1023 opal_clear_cmd(sess); 1024 opal_set_comid(sess, dev->comid); 1025 1026 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1027 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_C_PIN_MSID], 1028 OPAL_UID_LENGTH); 1029 opal_add_token_bytestring(&err, sess, spdk_opal_method[GET_METHOD], OPAL_UID_LENGTH); 1030 1031 opal_add_tokens(&err, sess, 12, SPDK_OPAL_STARTLIST, 1032 SPDK_OPAL_STARTLIST, 1033 SPDK_OPAL_STARTNAME, 1034 SPDK_OPAL_STARTCOLUMN, 1035 SPDK_OPAL_PIN, 1036 SPDK_OPAL_ENDNAME, 1037 SPDK_OPAL_STARTNAME, 1038 SPDK_OPAL_ENDCOLUMN, 1039 SPDK_OPAL_PIN, 1040 SPDK_OPAL_ENDNAME, 1041 SPDK_OPAL_ENDLIST, 1042 SPDK_OPAL_ENDLIST); 1043 1044 if (err) { 1045 SPDK_ERRLOG("Error building Get MSID CPIN PIN command.\n"); 1046 return err; 1047 } 1048 1049 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1050 if (ret) { 1051 return ret; 1052 } 1053 1054 ret = opal_send_recv(dev, sess); 1055 if (ret) { 1056 return ret; 1057 } 1058 1059 return opal_get_msid_cpin_pin_done(sess, opal_key); 1060 } 1061 1062 static int 1063 opal_build_generic_pw_cmd(struct opal_session *sess, uint8_t *key, size_t key_len, 1064 uint8_t *cpin_uid, struct spdk_opal_dev *dev) 1065 { 1066 int err = 0; 1067 1068 opal_clear_cmd(sess); 1069 opal_set_comid(sess, dev->comid); 1070 1071 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1072 opal_add_token_bytestring(&err, sess, cpin_uid, OPAL_UID_LENGTH); 1073 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], 1074 OPAL_UID_LENGTH); 1075 1076 opal_add_tokens(&err, sess, 6, 1077 SPDK_OPAL_STARTLIST, 1078 SPDK_OPAL_STARTNAME, 1079 SPDK_OPAL_VALUES, 1080 SPDK_OPAL_STARTLIST, 1081 SPDK_OPAL_STARTNAME, 1082 SPDK_OPAL_PIN); 1083 opal_add_token_bytestring(&err, sess, key, key_len); 1084 opal_add_tokens(&err, sess, 4, 1085 SPDK_OPAL_ENDNAME, 1086 SPDK_OPAL_ENDLIST, 1087 SPDK_OPAL_ENDNAME, 1088 SPDK_OPAL_ENDLIST); 1089 if (err) { 1090 return err; 1091 } 1092 1093 return opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1094 } 1095 1096 static int 1097 opal_get_locking_sp_lifecycle_done(struct opal_session *sess) 1098 { 1099 uint8_t lifecycle; 1100 int error = 0; 1101 1102 error = opal_parse_and_check_status(sess); 1103 if (error) { 1104 return error; 1105 } 1106 1107 lifecycle = opal_response_get_u64(&sess->parsed_resp, 4); 1108 if (lifecycle != OPAL_MANUFACTURED_INACTIVE) { /* status before activate */ 1109 SPDK_ERRLOG("Couldn't determine the status of the Lifecycle state\n"); 1110 return -EINVAL; 1111 } 1112 1113 return 0; 1114 } 1115 1116 static int 1117 opal_get_locking_sp_lifecycle(struct spdk_opal_dev *dev, struct opal_session *sess) 1118 { 1119 int err = 0; 1120 int ret; 1121 1122 opal_clear_cmd(sess); 1123 opal_set_comid(sess, dev->comid); 1124 1125 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1126 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_LOCKINGSP], 1127 OPAL_UID_LENGTH); 1128 opal_add_token_bytestring(&err, sess, spdk_opal_method[GET_METHOD], OPAL_UID_LENGTH); 1129 1130 opal_add_tokens(&err, sess, 12, SPDK_OPAL_STARTLIST, 1131 SPDK_OPAL_STARTLIST, 1132 SPDK_OPAL_STARTNAME, 1133 SPDK_OPAL_STARTCOLUMN, 1134 SPDK_OPAL_LIFECYCLE, 1135 SPDK_OPAL_ENDNAME, 1136 SPDK_OPAL_STARTNAME, 1137 SPDK_OPAL_ENDCOLUMN, 1138 SPDK_OPAL_LIFECYCLE, 1139 SPDK_OPAL_ENDNAME, 1140 SPDK_OPAL_ENDLIST, 1141 SPDK_OPAL_ENDLIST); 1142 1143 if (err) { 1144 SPDK_ERRLOG("Error Building GET Lifecycle Status command\n"); 1145 return err; 1146 } 1147 1148 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1149 if (ret) { 1150 return ret; 1151 } 1152 1153 ret = opal_send_recv(dev, sess); 1154 if (ret) { 1155 return ret; 1156 } 1157 1158 return opal_get_locking_sp_lifecycle_done(sess); 1159 } 1160 1161 static int 1162 opal_activate(struct spdk_opal_dev *dev, struct opal_session *sess) 1163 { 1164 int err = 0; 1165 int ret; 1166 1167 opal_clear_cmd(sess); 1168 opal_set_comid(sess, dev->comid); 1169 1170 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1171 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_LOCKINGSP], 1172 OPAL_UID_LENGTH); 1173 opal_add_token_bytestring(&err, sess, spdk_opal_method[ACTIVATE_METHOD], 1174 OPAL_UID_LENGTH); 1175 1176 opal_add_tokens(&err, sess, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST); 1177 1178 if (err) { 1179 SPDK_ERRLOG("Error building Activate LockingSP command.\n"); 1180 return err; 1181 } 1182 1183 /* TODO: Single User Mode for activation */ 1184 1185 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1186 if (ret) { 1187 return ret; 1188 } 1189 1190 ret = opal_send_recv(dev, sess); 1191 if (ret) { 1192 return ret; 1193 } 1194 1195 return opal_parse_and_check_status(sess); 1196 } 1197 1198 static int 1199 opal_start_auth_session(struct spdk_opal_dev *dev, 1200 struct opal_session *sess, 1201 enum spdk_opal_user user, 1202 struct spdk_opal_key *opal_key) 1203 { 1204 uint8_t uid_user[OPAL_UID_LENGTH]; 1205 int err = 0; 1206 int ret; 1207 uint32_t hsn = GENERIC_HOST_SESSION_NUM; 1208 1209 opal_clear_cmd(sess); 1210 opal_set_comid(sess, dev->comid); 1211 1212 if (user != OPAL_ADMIN1) { 1213 memcpy(uid_user, spdk_opal_uid[UID_USER1], OPAL_UID_LENGTH); 1214 uid_user[7] = user; 1215 } else { 1216 memcpy(uid_user, spdk_opal_uid[UID_ADMIN1], OPAL_UID_LENGTH); 1217 } 1218 1219 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1220 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_SMUID], 1221 OPAL_UID_LENGTH); 1222 opal_add_token_bytestring(&err, sess, spdk_opal_method[STARTSESSION_METHOD], 1223 OPAL_UID_LENGTH); 1224 1225 opal_add_token_u8(&err, sess, SPDK_OPAL_STARTLIST); 1226 opal_add_token_u64(&err, sess, hsn); 1227 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_LOCKINGSP], 1228 OPAL_UID_LENGTH); 1229 opal_add_tokens(&err, sess, 3, SPDK_OPAL_TRUE, SPDK_OPAL_STARTNAME, 1230 0); /* True for a Read-Write session */ 1231 opal_add_token_bytestring(&err, sess, opal_key->key, opal_key->key_len); 1232 opal_add_tokens(&err, sess, 3, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME, 3); /* HostSignAuth */ 1233 opal_add_token_bytestring(&err, sess, uid_user, OPAL_UID_LENGTH); 1234 opal_add_tokens(&err, sess, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_ENDLIST); 1235 1236 if (err) { 1237 SPDK_ERRLOG("Error building STARTSESSION command.\n"); 1238 return err; 1239 } 1240 1241 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1242 if (ret) { 1243 return ret; 1244 } 1245 1246 ret = opal_send_recv(dev, sess); 1247 if (ret) { 1248 return ret; 1249 } 1250 1251 return opal_start_session_done(sess); 1252 } 1253 1254 static int 1255 opal_lock_unlock_range(struct spdk_opal_dev *dev, struct opal_session *sess, 1256 enum spdk_opal_locking_range locking_range, 1257 enum spdk_opal_lock_state l_state) 1258 { 1259 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 1260 uint8_t read_locked, write_locked; 1261 int err = 0; 1262 int ret; 1263 1264 opal_clear_cmd(sess); 1265 opal_set_comid(sess, dev->comid); 1266 1267 opal_build_locking_range(uid_locking_range, locking_range); 1268 1269 switch (l_state) { 1270 case OPAL_READONLY: 1271 read_locked = 0; 1272 write_locked = 1; 1273 break; 1274 case OPAL_READWRITE: 1275 read_locked = 0; 1276 write_locked = 0; 1277 break; 1278 case OPAL_RWLOCK: 1279 read_locked = 1; 1280 write_locked = 1; 1281 break; 1282 default: 1283 SPDK_ERRLOG("Tried to set an invalid locking state.\n"); 1284 return -EINVAL; 1285 } 1286 1287 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1288 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 1289 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH); 1290 1291 opal_add_tokens(&err, sess, 15, SPDK_OPAL_STARTLIST, 1292 SPDK_OPAL_STARTNAME, 1293 SPDK_OPAL_VALUES, 1294 SPDK_OPAL_STARTLIST, 1295 SPDK_OPAL_STARTNAME, 1296 SPDK_OPAL_READLOCKED, 1297 read_locked, 1298 SPDK_OPAL_ENDNAME, 1299 SPDK_OPAL_STARTNAME, 1300 SPDK_OPAL_WRITELOCKED, 1301 write_locked, 1302 SPDK_OPAL_ENDNAME, 1303 SPDK_OPAL_ENDLIST, 1304 SPDK_OPAL_ENDNAME, 1305 SPDK_OPAL_ENDLIST); 1306 1307 if (err) { 1308 SPDK_ERRLOG("Error building SET command.\n"); 1309 return err; 1310 } 1311 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1312 if (ret) { 1313 return ret; 1314 } 1315 1316 ret = opal_send_recv(dev, sess); 1317 if (ret) { 1318 return ret; 1319 } 1320 1321 return opal_parse_and_check_status(sess); 1322 } 1323 1324 static int 1325 opal_generic_locking_range_enable_disable(struct spdk_opal_dev *dev, 1326 struct opal_session *sess, 1327 uint8_t *uid, bool read_lock_enabled, bool write_lock_enabled) 1328 { 1329 int err = 0; 1330 1331 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1332 opal_add_token_bytestring(&err, sess, uid, OPAL_UID_LENGTH); 1333 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH); 1334 1335 opal_add_tokens(&err, sess, 23, SPDK_OPAL_STARTLIST, 1336 SPDK_OPAL_STARTNAME, 1337 SPDK_OPAL_VALUES, 1338 SPDK_OPAL_STARTLIST, 1339 1340 SPDK_OPAL_STARTNAME, 1341 SPDK_OPAL_READLOCKENABLED, 1342 read_lock_enabled, 1343 SPDK_OPAL_ENDNAME, 1344 1345 SPDK_OPAL_STARTNAME, 1346 SPDK_OPAL_WRITELOCKENABLED, 1347 write_lock_enabled, 1348 SPDK_OPAL_ENDNAME, 1349 1350 SPDK_OPAL_STARTNAME, 1351 SPDK_OPAL_READLOCKED, 1352 0, 1353 SPDK_OPAL_ENDNAME, 1354 1355 SPDK_OPAL_STARTNAME, 1356 SPDK_OPAL_WRITELOCKED, 1357 0, 1358 SPDK_OPAL_ENDNAME, 1359 1360 SPDK_OPAL_ENDLIST, 1361 SPDK_OPAL_ENDNAME, 1362 SPDK_OPAL_ENDLIST); 1363 if (err) { 1364 SPDK_ERRLOG("Error building locking range enable/disable command.\n"); 1365 } 1366 return err; 1367 } 1368 1369 static int 1370 opal_setup_locking_range(struct spdk_opal_dev *dev, struct opal_session *sess, 1371 enum spdk_opal_locking_range locking_range, 1372 uint64_t range_start, uint64_t range_length, 1373 bool read_lock_enabled, bool write_lock_enabled) 1374 { 1375 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 1376 int err = 0; 1377 int ret; 1378 1379 opal_clear_cmd(sess); 1380 opal_set_comid(sess, dev->comid); 1381 1382 opal_build_locking_range(uid_locking_range, locking_range); 1383 1384 if (locking_range == 0) { 1385 err = opal_generic_locking_range_enable_disable(dev, sess, uid_locking_range, 1386 read_lock_enabled, write_lock_enabled); 1387 } else { 1388 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1389 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 1390 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], 1391 OPAL_UID_LENGTH); 1392 1393 opal_add_tokens(&err, sess, 6, 1394 SPDK_OPAL_STARTLIST, 1395 SPDK_OPAL_STARTNAME, 1396 SPDK_OPAL_VALUES, 1397 SPDK_OPAL_STARTLIST, 1398 SPDK_OPAL_STARTNAME, 1399 SPDK_OPAL_RANGESTART); 1400 opal_add_token_u64(&err, sess, range_start); 1401 opal_add_tokens(&err, sess, 3, 1402 SPDK_OPAL_ENDNAME, 1403 SPDK_OPAL_STARTNAME, 1404 SPDK_OPAL_RANGELENGTH); 1405 opal_add_token_u64(&err, sess, range_length); 1406 opal_add_tokens(&err, sess, 3, 1407 SPDK_OPAL_ENDNAME, 1408 SPDK_OPAL_STARTNAME, 1409 SPDK_OPAL_READLOCKENABLED); 1410 opal_add_token_u64(&err, sess, read_lock_enabled); 1411 opal_add_tokens(&err, sess, 3, 1412 SPDK_OPAL_ENDNAME, 1413 SPDK_OPAL_STARTNAME, 1414 SPDK_OPAL_WRITELOCKENABLED); 1415 opal_add_token_u64(&err, sess, write_lock_enabled); 1416 opal_add_tokens(&err, sess, 4, 1417 SPDK_OPAL_ENDNAME, 1418 SPDK_OPAL_ENDLIST, 1419 SPDK_OPAL_ENDNAME, 1420 SPDK_OPAL_ENDLIST); 1421 } 1422 if (err) { 1423 SPDK_ERRLOG("Error building Setup Locking range command.\n"); 1424 return err; 1425 1426 } 1427 1428 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1429 if (ret) { 1430 return ret; 1431 } 1432 1433 ret = opal_send_recv(dev, sess); 1434 if (ret) { 1435 return ret; 1436 } 1437 1438 return opal_parse_and_check_status(sess); 1439 } 1440 1441 static int 1442 opal_get_max_ranges_done(struct opal_session *sess) 1443 { 1444 int error = 0; 1445 1446 error = opal_parse_and_check_status(sess); 1447 if (error) { 1448 return error; 1449 } 1450 1451 /* "MaxRanges" is token 4 of response */ 1452 return opal_response_get_u16(&sess->parsed_resp, 4); 1453 } 1454 1455 static int 1456 opal_get_max_ranges(struct spdk_opal_dev *dev, struct opal_session *sess) 1457 { 1458 int err = 0; 1459 int ret; 1460 1461 opal_clear_cmd(sess); 1462 opal_set_comid(sess, dev->comid); 1463 1464 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1465 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_LOCKING_INFO_TABLE], 1466 OPAL_UID_LENGTH); 1467 opal_add_token_bytestring(&err, sess, spdk_opal_method[GET_METHOD], OPAL_UID_LENGTH); 1468 1469 opal_add_tokens(&err, sess, 12, SPDK_OPAL_STARTLIST, 1470 SPDK_OPAL_STARTLIST, 1471 SPDK_OPAL_STARTNAME, 1472 SPDK_OPAL_STARTCOLUMN, 1473 SPDK_OPAL_MAXRANGES, 1474 SPDK_OPAL_ENDNAME, 1475 SPDK_OPAL_STARTNAME, 1476 SPDK_OPAL_ENDCOLUMN, 1477 SPDK_OPAL_MAXRANGES, 1478 SPDK_OPAL_ENDNAME, 1479 SPDK_OPAL_ENDLIST, 1480 SPDK_OPAL_ENDLIST); 1481 1482 if (err) { 1483 SPDK_ERRLOG("Error Building GET Lifecycle Status command\n"); 1484 return err; 1485 } 1486 1487 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1488 if (ret) { 1489 return ret; 1490 } 1491 1492 ret = opal_send_recv(dev, sess); 1493 if (ret) { 1494 return ret; 1495 } 1496 1497 return opal_get_max_ranges_done(sess); 1498 } 1499 1500 static int 1501 opal_get_locking_range_info_done(struct opal_session *sess, 1502 struct spdk_opal_locking_range_info *info) 1503 { 1504 int error = 0; 1505 1506 error = opal_parse_and_check_status(sess); 1507 if (error) { 1508 return error; 1509 } 1510 1511 info->range_start = opal_response_get_u64(&sess->parsed_resp, 4); 1512 info->range_length = opal_response_get_u64(&sess->parsed_resp, 8); 1513 info->read_lock_enabled = opal_response_get_u8(&sess->parsed_resp, 12); 1514 info->write_lock_enabled = opal_response_get_u8(&sess->parsed_resp, 16); 1515 info->read_locked = opal_response_get_u8(&sess->parsed_resp, 20); 1516 info->write_locked = opal_response_get_u8(&sess->parsed_resp, 24); 1517 1518 return 0; 1519 } 1520 1521 static int 1522 opal_get_locking_range_info(struct spdk_opal_dev *dev, 1523 struct opal_session *sess, 1524 enum spdk_opal_locking_range locking_range_id) 1525 { 1526 int err = 0; 1527 int ret; 1528 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 1529 struct spdk_opal_locking_range_info *info; 1530 1531 opal_build_locking_range(uid_locking_range, locking_range_id); 1532 1533 assert(locking_range_id < SPDK_OPAL_MAX_LOCKING_RANGE); 1534 info = &dev->locking_ranges[locking_range_id]; 1535 memset(info, 0, sizeof(*info)); 1536 info->locking_range_id = locking_range_id; 1537 1538 opal_clear_cmd(sess); 1539 opal_set_comid(sess, dev->comid); 1540 1541 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1542 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 1543 opal_add_token_bytestring(&err, sess, spdk_opal_method[GET_METHOD], OPAL_UID_LENGTH); 1544 1545 1546 opal_add_tokens(&err, sess, 12, SPDK_OPAL_STARTLIST, 1547 SPDK_OPAL_STARTLIST, 1548 SPDK_OPAL_STARTNAME, 1549 SPDK_OPAL_STARTCOLUMN, 1550 SPDK_OPAL_RANGESTART, 1551 SPDK_OPAL_ENDNAME, 1552 SPDK_OPAL_STARTNAME, 1553 SPDK_OPAL_ENDCOLUMN, 1554 SPDK_OPAL_WRITELOCKED, 1555 SPDK_OPAL_ENDNAME, 1556 SPDK_OPAL_ENDLIST, 1557 SPDK_OPAL_ENDLIST); 1558 1559 if (err) { 1560 SPDK_ERRLOG("Error Building get locking range info command\n"); 1561 return err; 1562 } 1563 1564 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1565 if (ret) { 1566 return ret; 1567 } 1568 1569 ret = opal_send_recv(dev, sess); 1570 if (ret) { 1571 return ret; 1572 } 1573 1574 return opal_get_locking_range_info_done(sess, info); 1575 } 1576 1577 static int 1578 opal_enable_user(struct spdk_opal_dev *dev, struct opal_session *sess, 1579 enum spdk_opal_user user) 1580 { 1581 int err = 0; 1582 int ret; 1583 uint8_t uid_user[OPAL_UID_LENGTH]; 1584 1585 memcpy(uid_user, spdk_opal_uid[UID_USER1], OPAL_UID_LENGTH); 1586 uid_user[7] = user; 1587 1588 opal_clear_cmd(sess); 1589 opal_set_comid(sess, dev->comid); 1590 1591 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1592 opal_add_token_bytestring(&err, sess, uid_user, OPAL_UID_LENGTH); 1593 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH); 1594 1595 opal_add_tokens(&err, sess, 11, 1596 SPDK_OPAL_STARTLIST, 1597 SPDK_OPAL_STARTNAME, 1598 SPDK_OPAL_VALUES, 1599 SPDK_OPAL_STARTLIST, 1600 SPDK_OPAL_STARTNAME, 1601 SPDK_OPAL_AUTH_ENABLE, 1602 SPDK_OPAL_TRUE, 1603 SPDK_OPAL_ENDNAME, 1604 SPDK_OPAL_ENDLIST, 1605 SPDK_OPAL_ENDNAME, 1606 SPDK_OPAL_ENDLIST); 1607 1608 if (err) { 1609 SPDK_ERRLOG("Error Building enable user command\n"); 1610 return err; 1611 } 1612 1613 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1614 if (ret) { 1615 return ret; 1616 } 1617 1618 ret = opal_send_recv(dev, sess); 1619 if (ret) { 1620 return ret; 1621 } 1622 1623 return opal_parse_and_check_status(sess); 1624 } 1625 1626 static int 1627 opal_add_user_to_locking_range(struct spdk_opal_dev *dev, 1628 struct opal_session *sess, 1629 enum spdk_opal_user user, 1630 enum spdk_opal_locking_range locking_range, 1631 enum spdk_opal_lock_state l_state) 1632 { 1633 int err = 0; 1634 int ret; 1635 uint8_t uid_user[OPAL_UID_LENGTH]; 1636 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 1637 1638 memcpy(uid_user, spdk_opal_uid[UID_USER1], OPAL_UID_LENGTH); 1639 uid_user[7] = user; 1640 1641 switch (l_state) { 1642 case OPAL_READONLY: 1643 memcpy(uid_locking_range, spdk_opal_uid[UID_LOCKINGRANGE_ACE_RDLOCKED], OPAL_UID_LENGTH); 1644 break; 1645 case OPAL_READWRITE: 1646 memcpy(uid_locking_range, spdk_opal_uid[UID_LOCKINGRANGE_ACE_WRLOCKED], OPAL_UID_LENGTH); 1647 break; 1648 default: 1649 SPDK_ERRLOG("locking state should only be OPAL_READONLY or OPAL_READWRITE\n"); 1650 return -EINVAL; 1651 } 1652 1653 uid_locking_range[7] = locking_range; 1654 1655 opal_clear_cmd(sess); 1656 opal_set_comid(sess, dev->comid); 1657 1658 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1659 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 1660 opal_add_token_bytestring(&err, sess, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH); 1661 1662 opal_add_tokens(&err, sess, 8, 1663 SPDK_OPAL_STARTLIST, 1664 SPDK_OPAL_STARTNAME, 1665 SPDK_OPAL_VALUES, 1666 SPDK_OPAL_STARTLIST, 1667 SPDK_OPAL_STARTNAME, 1668 SPDK_OPAL_BOOLEAN_EXPR, 1669 SPDK_OPAL_STARTLIST, 1670 SPDK_OPAL_STARTNAME); 1671 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_HALF_AUTHORITY_OBJ_REF], 1672 OPAL_UID_LENGTH / 2); 1673 opal_add_token_bytestring(&err, sess, uid_user, OPAL_UID_LENGTH); 1674 1675 opal_add_tokens(&err, sess, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME); 1676 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_HALF_AUTHORITY_OBJ_REF], 1677 OPAL_UID_LENGTH / 2); 1678 opal_add_token_bytestring(&err, sess, uid_user, OPAL_UID_LENGTH); 1679 1680 opal_add_tokens(&err, sess, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME); 1681 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_HALF_BOOLEAN_ACE], OPAL_UID_LENGTH / 2); 1682 opal_add_tokens(&err, sess, 7, 1683 SPDK_OPAL_TRUE, 1684 SPDK_OPAL_ENDNAME, 1685 SPDK_OPAL_ENDLIST, 1686 SPDK_OPAL_ENDNAME, 1687 SPDK_OPAL_ENDLIST, 1688 SPDK_OPAL_ENDNAME, 1689 SPDK_OPAL_ENDLIST); 1690 if (err) { 1691 SPDK_ERRLOG("Error building add user to locking range command\n"); 1692 return err; 1693 } 1694 1695 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1696 if (ret) { 1697 return ret; 1698 } 1699 1700 ret = opal_send_recv(dev, sess); 1701 if (ret) { 1702 return ret; 1703 } 1704 1705 return opal_parse_and_check_status(sess); 1706 } 1707 1708 static int 1709 opal_new_user_passwd(struct spdk_opal_dev *dev, struct opal_session *sess, 1710 enum spdk_opal_user user, 1711 struct spdk_opal_key *opal_key) 1712 { 1713 uint8_t uid_cpin[OPAL_UID_LENGTH]; 1714 int ret; 1715 1716 if (user == OPAL_ADMIN1) { 1717 memcpy(uid_cpin, spdk_opal_uid[UID_C_PIN_ADMIN1], OPAL_UID_LENGTH); 1718 } else { 1719 memcpy(uid_cpin, spdk_opal_uid[UID_C_PIN_USER1], OPAL_UID_LENGTH); 1720 uid_cpin[7] = user; 1721 } 1722 1723 ret = opal_build_generic_pw_cmd(sess, opal_key->key, opal_key->key_len, uid_cpin, dev); 1724 if (ret != 0) { 1725 SPDK_ERRLOG("Error building set password command\n"); 1726 return ret; 1727 } 1728 1729 ret = opal_send_recv(dev, sess); 1730 if (ret) { 1731 return ret; 1732 } 1733 1734 return opal_parse_and_check_status(sess); 1735 } 1736 1737 static int 1738 opal_set_sid_cpin_pin(struct spdk_opal_dev *dev, struct opal_session *sess, char *new_passwd) 1739 { 1740 uint8_t cpin_uid[OPAL_UID_LENGTH]; 1741 struct spdk_opal_key opal_key = {}; 1742 int ret; 1743 1744 ret = opal_init_key(&opal_key, new_passwd); 1745 if (ret != 0) { 1746 return ret; 1747 } 1748 1749 memcpy(cpin_uid, spdk_opal_uid[UID_C_PIN_SID], OPAL_UID_LENGTH); 1750 1751 if (opal_build_generic_pw_cmd(sess, opal_key.key, opal_key.key_len, cpin_uid, dev)) { 1752 SPDK_ERRLOG("Error building Set SID cpin\n"); 1753 return -ERANGE; 1754 } 1755 1756 ret = opal_send_recv(dev, sess); 1757 if (ret) { 1758 return ret; 1759 } 1760 1761 return opal_parse_and_check_status(sess); 1762 } 1763 1764 int 1765 spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd) 1766 { 1767 int ret; 1768 struct spdk_opal_key opal_key = {}; 1769 struct opal_session *sess; 1770 1771 assert(dev != NULL); 1772 1773 sess = opal_alloc_session(dev); 1774 if (!sess) { 1775 return -ENOMEM; 1776 } 1777 1778 ret = opal_start_generic_session(dev, sess, UID_ANYBODY, UID_ADMINSP, NULL, 0); 1779 if (ret) { 1780 SPDK_ERRLOG("start admin SP session error %d\n", ret); 1781 goto end; 1782 } 1783 1784 ret = opal_get_msid_cpin_pin(dev, sess, &opal_key); 1785 if (ret) { 1786 SPDK_ERRLOG("get msid error %d\n", ret); 1787 opal_end_session(dev, sess, dev->comid); 1788 goto end; 1789 } 1790 1791 ret = opal_end_session(dev, sess, dev->comid); 1792 if (ret) { 1793 SPDK_ERRLOG("end session error %d\n", ret); 1794 goto end; 1795 } 1796 1797 /* reuse the session structure */ 1798 memset(sess, 0, sizeof(*sess)); 1799 sess->dev = dev; 1800 ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP, 1801 opal_key.key, opal_key.key_len); 1802 if (ret) { 1803 SPDK_ERRLOG("start admin SP session error %d\n", ret); 1804 goto end; 1805 } 1806 memset(&opal_key, 0, sizeof(struct spdk_opal_key)); 1807 1808 ret = opal_set_sid_cpin_pin(dev, sess, new_passwd); 1809 if (ret) { 1810 SPDK_ERRLOG("set cpin error %d\n", ret); 1811 opal_end_session(dev, sess, dev->comid); 1812 goto end; 1813 } 1814 1815 ret = opal_end_session(dev, sess, dev->comid); 1816 if (ret) { 1817 SPDK_ERRLOG("end session error %d\n", ret); 1818 } 1819 1820 end: 1821 free(sess); 1822 return ret; 1823 } 1824 1825 struct spdk_opal_dev * 1826 spdk_opal_dev_construct(struct spdk_nvme_ctrlr *ctrlr) 1827 { 1828 struct spdk_opal_dev *dev; 1829 void *payload; 1830 1831 dev = calloc(1, sizeof(*dev)); 1832 if (!dev) { 1833 SPDK_ERRLOG("Memory allocation failed\n"); 1834 return NULL; 1835 } 1836 1837 dev->ctrlr = ctrlr; 1838 1839 payload = calloc(1, IO_BUFFER_LENGTH); 1840 if (!payload) { 1841 free(dev); 1842 return NULL; 1843 } 1844 1845 if (opal_discovery0(dev, payload, IO_BUFFER_LENGTH)) { 1846 SPDK_INFOLOG(opal, "Opal is not supported on this device\n"); 1847 free(dev); 1848 free(payload); 1849 return NULL; 1850 } 1851 1852 free(payload); 1853 return dev; 1854 } 1855 1856 static int 1857 opal_build_revert_tper_cmd(struct spdk_opal_dev *dev, struct opal_session *sess) 1858 { 1859 int err = 0; 1860 1861 opal_clear_cmd(sess); 1862 opal_set_comid(sess, dev->comid); 1863 1864 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1865 opal_add_token_bytestring(&err, sess, spdk_opal_uid[UID_ADMINSP], 1866 OPAL_UID_LENGTH); 1867 opal_add_token_bytestring(&err, sess, spdk_opal_method[REVERT_METHOD], 1868 OPAL_UID_LENGTH); 1869 opal_add_token_u8(&err, sess, SPDK_OPAL_STARTLIST); 1870 opal_add_token_u8(&err, sess, SPDK_OPAL_ENDLIST); 1871 if (err) { 1872 SPDK_ERRLOG("Error building REVERT TPER command.\n"); 1873 return -ERANGE; 1874 } 1875 1876 return opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1877 } 1878 1879 static int 1880 opal_gen_new_active_key(struct spdk_opal_dev *dev, struct opal_session *sess, 1881 struct spdk_opal_key *active_key) 1882 { 1883 uint8_t uid_data[OPAL_UID_LENGTH] = {0}; 1884 int err = 0; 1885 int length; 1886 int ret; 1887 1888 opal_clear_cmd(sess); 1889 opal_set_comid(sess, dev->comid); 1890 1891 if (active_key->key_len == 0) { 1892 SPDK_ERRLOG("Error finding previous data to generate new active key\n"); 1893 return -EINVAL; 1894 } 1895 1896 length = spdk_min(active_key->key_len, OPAL_UID_LENGTH); 1897 memcpy(uid_data, active_key->key, length); 1898 1899 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1900 opal_add_token_bytestring(&err, sess, uid_data, OPAL_UID_LENGTH); 1901 opal_add_token_bytestring(&err, sess, spdk_opal_method[GENKEY_METHOD], 1902 OPAL_UID_LENGTH); 1903 1904 opal_add_tokens(&err, sess, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST); 1905 1906 if (err) { 1907 SPDK_ERRLOG("Error building new key generation command.\n"); 1908 return err; 1909 } 1910 1911 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1912 if (ret) { 1913 return ret; 1914 } 1915 1916 ret = opal_send_recv(dev, sess); 1917 if (ret) { 1918 return ret; 1919 } 1920 1921 return opal_parse_and_check_status(sess); 1922 } 1923 1924 static int 1925 opal_get_active_key_done(struct opal_session *sess, struct spdk_opal_key *active_key) 1926 { 1927 const char *key; 1928 size_t str_len; 1929 int error = 0; 1930 1931 error = opal_parse_and_check_status(sess); 1932 if (error) { 1933 return error; 1934 } 1935 1936 str_len = opal_response_get_string(&sess->parsed_resp, 4, &key); 1937 if (!key) { 1938 SPDK_ERRLOG("Couldn't extract active key from response\n"); 1939 return -EINVAL; 1940 } 1941 1942 active_key->key_len = str_len; 1943 memcpy(active_key->key, key, active_key->key_len); 1944 1945 SPDK_DEBUGLOG(opal, "active key = %p\n", active_key->key); 1946 return 0; 1947 } 1948 1949 static int 1950 opal_get_active_key(struct spdk_opal_dev *dev, struct opal_session *sess, 1951 enum spdk_opal_locking_range locking_range, 1952 struct spdk_opal_key *active_key) 1953 { 1954 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 1955 int err = 0; 1956 int ret; 1957 1958 opal_clear_cmd(sess); 1959 opal_set_comid(sess, dev->comid); 1960 1961 opal_build_locking_range(uid_locking_range, locking_range); 1962 1963 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 1964 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 1965 opal_add_token_bytestring(&err, sess, spdk_opal_method[GET_METHOD], 1966 OPAL_UID_LENGTH); 1967 opal_add_tokens(&err, sess, 12, 1968 SPDK_OPAL_STARTLIST, 1969 SPDK_OPAL_STARTLIST, 1970 SPDK_OPAL_STARTNAME, 1971 SPDK_OPAL_STARTCOLUMN, 1972 SPDK_OPAL_ACTIVEKEY, 1973 SPDK_OPAL_ENDNAME, 1974 SPDK_OPAL_STARTNAME, 1975 SPDK_OPAL_ENDCOLUMN, 1976 SPDK_OPAL_ACTIVEKEY, 1977 SPDK_OPAL_ENDNAME, 1978 SPDK_OPAL_ENDLIST, 1979 SPDK_OPAL_ENDLIST); 1980 1981 if (err) { 1982 SPDK_ERRLOG("Error building get active key command.\n"); 1983 return err; 1984 } 1985 1986 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 1987 if (ret) { 1988 return ret; 1989 } 1990 1991 ret = opal_send_recv(dev, sess); 1992 if (ret) { 1993 return ret; 1994 } 1995 1996 return opal_get_active_key_done(sess, active_key); 1997 } 1998 1999 static int 2000 opal_erase_locking_range(struct spdk_opal_dev *dev, struct opal_session *sess, 2001 enum spdk_opal_locking_range locking_range) 2002 { 2003 uint8_t uid_locking_range[OPAL_UID_LENGTH]; 2004 int err = 0; 2005 int ret; 2006 2007 opal_clear_cmd(sess); 2008 opal_set_comid(sess, dev->comid); 2009 2010 opal_build_locking_range(uid_locking_range, locking_range); 2011 2012 opal_add_token_u8(&err, sess, SPDK_OPAL_CALL); 2013 opal_add_token_bytestring(&err, sess, uid_locking_range, OPAL_UID_LENGTH); 2014 opal_add_token_bytestring(&err, sess, spdk_opal_method[ERASE_METHOD], 2015 OPAL_UID_LENGTH); 2016 opal_add_tokens(&err, sess, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST); 2017 2018 if (err) { 2019 SPDK_ERRLOG("Error building erase locking range.\n"); 2020 return err; 2021 } 2022 2023 ret = opal_cmd_finalize(sess, sess->hsn, sess->tsn, true); 2024 if (ret) { 2025 return ret; 2026 } 2027 2028 ret = opal_send_recv(dev, sess); 2029 if (ret) { 2030 return ret; 2031 } 2032 2033 return opal_parse_and_check_status(sess); 2034 } 2035 2036 int 2037 spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd) 2038 { 2039 int ret; 2040 struct opal_session *sess; 2041 struct spdk_opal_key opal_key = {}; 2042 2043 assert(dev != NULL); 2044 2045 ret = opal_init_key(&opal_key, passwd); 2046 if (ret) { 2047 SPDK_ERRLOG("Init key failed\n"); 2048 return ret; 2049 } 2050 2051 sess = opal_alloc_session(dev); 2052 if (!sess) { 2053 return -ENOMEM; 2054 } 2055 2056 ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP, 2057 opal_key.key, opal_key.key_len); 2058 if (ret) { 2059 SPDK_ERRLOG("Error on starting admin SP session with error %d\n", ret); 2060 free(sess); 2061 return ret; 2062 } 2063 2064 ret = opal_build_revert_tper_cmd(dev, sess); 2065 if (ret) { 2066 opal_end_session(dev, sess, dev->comid); 2067 SPDK_ERRLOG("Build revert tper command with error %d\n", ret); 2068 goto end; 2069 } 2070 2071 ret = opal_send_recv(dev, sess); 2072 if (ret) { 2073 opal_end_session(dev, sess, dev->comid); 2074 SPDK_ERRLOG("Error on reverting TPer with error %d\n", ret); 2075 goto end; 2076 } 2077 2078 ret = opal_parse_and_check_status(sess); 2079 if (ret) { 2080 opal_end_session(dev, sess, dev->comid); 2081 SPDK_ERRLOG("Error on reverting TPer with error %d\n", ret); 2082 } 2083 /* No opal_end_session() required here for successful case */ 2084 2085 end: 2086 free(sess); 2087 return ret; 2088 } 2089 2090 int 2091 spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd) 2092 { 2093 struct opal_session *sess; 2094 struct spdk_opal_key opal_key = {}; 2095 int ret; 2096 2097 ret = opal_init_key(&opal_key, passwd); 2098 if (ret != 0) { 2099 return ret; 2100 } 2101 2102 sess = opal_alloc_session(dev); 2103 if (!sess) { 2104 return -ENOMEM; 2105 } 2106 2107 ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP, 2108 opal_key.key, opal_key.key_len); 2109 if (ret) { 2110 SPDK_ERRLOG("Error on starting admin SP session with error %d\n", ret); 2111 free(sess); 2112 return ret; 2113 } 2114 2115 ret = opal_get_locking_sp_lifecycle(dev, sess); 2116 if (ret) { 2117 SPDK_ERRLOG("Error on getting SP lifecycle with error %d\n", ret); 2118 goto end; 2119 } 2120 2121 ret = opal_activate(dev, sess); 2122 if (ret) { 2123 SPDK_ERRLOG("Error on activation with error %d\n", ret); 2124 } 2125 2126 end: 2127 ret += opal_end_session(dev, sess, dev->comid); 2128 if (ret) { 2129 SPDK_ERRLOG("Error on ending session with error %d\n", ret); 2130 } 2131 2132 free(sess); 2133 return ret; 2134 } 2135 2136 int 2137 spdk_opal_cmd_lock_unlock(struct spdk_opal_dev *dev, enum spdk_opal_user user, 2138 enum spdk_opal_lock_state flag, enum spdk_opal_locking_range locking_range, 2139 const char *passwd) 2140 { 2141 struct opal_session *sess; 2142 struct spdk_opal_key opal_key = {}; 2143 int ret; 2144 2145 assert(dev != NULL); 2146 2147 ret = opal_init_key(&opal_key, passwd); 2148 if (ret != 0) { 2149 return ret; 2150 } 2151 2152 sess = opal_alloc_session(dev); 2153 if (!sess) { 2154 return -ENOMEM; 2155 } 2156 2157 ret = opal_start_auth_session(dev, sess, user, &opal_key); 2158 if (ret) { 2159 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2160 free(sess); 2161 return ret; 2162 } 2163 2164 ret = opal_lock_unlock_range(dev, sess, locking_range, flag); 2165 if (ret) { 2166 SPDK_ERRLOG("lock unlock range error %d\n", ret); 2167 } 2168 2169 ret += opal_end_session(dev, sess, dev->comid); 2170 if (ret) { 2171 SPDK_ERRLOG("end session error %d\n", ret); 2172 } 2173 2174 free(sess); 2175 return ret; 2176 } 2177 2178 int 2179 spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user, 2180 enum spdk_opal_locking_range locking_range_id, uint64_t range_start, 2181 uint64_t range_length, const char *passwd) 2182 { 2183 struct opal_session *sess; 2184 struct spdk_opal_key opal_key = {}; 2185 int ret; 2186 2187 assert(dev != NULL); 2188 2189 ret = opal_init_key(&opal_key, passwd); 2190 if (ret != 0) { 2191 return ret; 2192 } 2193 2194 sess = opal_alloc_session(dev); 2195 if (!sess) { 2196 return -ENOMEM; 2197 } 2198 2199 ret = opal_start_auth_session(dev, sess, user, &opal_key); 2200 if (ret) { 2201 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2202 free(sess); 2203 return ret; 2204 } 2205 2206 ret = opal_setup_locking_range(dev, sess, locking_range_id, range_start, range_length, true, 2207 true); 2208 if (ret) { 2209 SPDK_ERRLOG("setup locking range error %d\n", ret); 2210 } 2211 2212 ret += opal_end_session(dev, sess, dev->comid); 2213 if (ret) { 2214 SPDK_ERRLOG("end session error %d\n", ret); 2215 } 2216 2217 free(sess); 2218 return ret; 2219 } 2220 2221 int 2222 spdk_opal_cmd_get_max_ranges(struct spdk_opal_dev *dev, const char *passwd) 2223 { 2224 struct opal_session *sess; 2225 struct spdk_opal_key opal_key = {}; 2226 int ret; 2227 2228 assert(dev != NULL); 2229 2230 if (dev->max_ranges) { 2231 return dev->max_ranges; 2232 } 2233 2234 ret = opal_init_key(&opal_key, passwd); 2235 if (ret != 0) { 2236 return ret; 2237 } 2238 2239 sess = opal_alloc_session(dev); 2240 if (!sess) { 2241 return -ENOMEM; 2242 } 2243 2244 ret = opal_start_auth_session(dev, sess, OPAL_ADMIN1, &opal_key); 2245 if (ret) { 2246 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2247 free(sess); 2248 return ret; 2249 } 2250 2251 ret = opal_get_max_ranges(dev, sess); 2252 if (ret > 0) { 2253 dev->max_ranges = ret; 2254 } 2255 2256 ret = opal_end_session(dev, sess, dev->comid); 2257 if (ret) { 2258 SPDK_ERRLOG("end session error %d\n", ret); 2259 } 2260 2261 free(sess); 2262 2263 return (ret == 0 ? dev->max_ranges : ret); 2264 } 2265 2266 int 2267 spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *passwd, 2268 enum spdk_opal_user user_id, 2269 enum spdk_opal_locking_range locking_range_id) 2270 { 2271 struct opal_session *sess; 2272 struct spdk_opal_key opal_key = {}; 2273 int ret; 2274 2275 assert(dev != NULL); 2276 2277 ret = opal_init_key(&opal_key, passwd); 2278 if (ret != 0) { 2279 return ret; 2280 } 2281 2282 sess = opal_alloc_session(dev); 2283 if (!sess) { 2284 return -ENOMEM; 2285 } 2286 2287 ret = opal_start_auth_session(dev, sess, user_id, &opal_key); 2288 if (ret) { 2289 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2290 free(sess); 2291 return ret; 2292 } 2293 2294 ret = opal_get_locking_range_info(dev, sess, locking_range_id); 2295 if (ret) { 2296 SPDK_ERRLOG("get locking range info error %d\n", ret); 2297 } 2298 2299 ret += opal_end_session(dev, sess, dev->comid); 2300 if (ret) { 2301 SPDK_ERRLOG("end session error %d\n", ret); 2302 } 2303 2304 free(sess); 2305 return ret; 2306 } 2307 2308 int 2309 spdk_opal_cmd_enable_user(struct spdk_opal_dev *dev, enum spdk_opal_user user_id, 2310 const char *passwd) 2311 { 2312 struct opal_session *sess; 2313 struct spdk_opal_key opal_key = {}; 2314 int ret; 2315 2316 assert(dev != NULL); 2317 2318 ret = opal_init_key(&opal_key, passwd); 2319 if (ret != 0) { 2320 return ret; 2321 } 2322 2323 sess = opal_alloc_session(dev); 2324 if (!sess) { 2325 return -ENOMEM; 2326 } 2327 2328 ret = opal_start_generic_session(dev, sess, UID_ADMIN1, UID_LOCKINGSP, 2329 opal_key.key, opal_key.key_len); 2330 if (ret) { 2331 SPDK_ERRLOG("start locking SP session error %d\n", ret); 2332 free(sess); 2333 return ret; 2334 } 2335 2336 ret = opal_enable_user(dev, sess, user_id); 2337 if (ret) { 2338 SPDK_ERRLOG("enable user error %d\n", ret); 2339 } 2340 2341 ret += opal_end_session(dev, sess, dev->comid); 2342 if (ret) { 2343 SPDK_ERRLOG("end session error %d\n", ret); 2344 } 2345 2346 free(sess); 2347 return ret; 2348 } 2349 2350 int 2351 spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id, 2352 enum spdk_opal_locking_range locking_range_id, 2353 enum spdk_opal_lock_state lock_flag, const char *passwd) 2354 { 2355 struct opal_session *sess; 2356 struct spdk_opal_key opal_key = {}; 2357 int ret; 2358 2359 assert(dev != NULL); 2360 2361 ret = opal_init_key(&opal_key, passwd); 2362 if (ret != 0) { 2363 return ret; 2364 } 2365 2366 sess = opal_alloc_session(dev); 2367 if (!sess) { 2368 return -ENOMEM; 2369 } 2370 2371 ret = opal_start_generic_session(dev, sess, UID_ADMIN1, UID_LOCKINGSP, 2372 opal_key.key, opal_key.key_len); 2373 if (ret) { 2374 SPDK_ERRLOG("start locking SP session error %d\n", ret); 2375 free(sess); 2376 return ret; 2377 } 2378 2379 ret = opal_add_user_to_locking_range(dev, sess, user_id, locking_range_id, lock_flag); 2380 if (ret) { 2381 SPDK_ERRLOG("add user to locking range error %d\n", ret); 2382 } 2383 2384 ret += opal_end_session(dev, sess, dev->comid); 2385 if (ret) { 2386 SPDK_ERRLOG("end session error %d\n", ret); 2387 } 2388 2389 free(sess); 2390 return ret; 2391 } 2392 2393 int 2394 spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user_id, 2395 const char *new_passwd, const char *old_passwd, bool new_user) 2396 { 2397 struct opal_session *sess; 2398 struct spdk_opal_key old_key = {}; 2399 struct spdk_opal_key new_key = {}; 2400 int ret; 2401 2402 assert(dev != NULL); 2403 2404 ret = opal_init_key(&old_key, old_passwd); 2405 if (ret != 0) { 2406 return ret; 2407 } 2408 2409 ret = opal_init_key(&new_key, new_passwd); 2410 if (ret != 0) { 2411 return ret; 2412 } 2413 2414 sess = opal_alloc_session(dev); 2415 if (!sess) { 2416 return -ENOMEM; 2417 } 2418 2419 ret = opal_start_auth_session(dev, sess, new_user ? OPAL_ADMIN1 : user_id, 2420 &old_key); 2421 if (ret) { 2422 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2423 free(sess); 2424 return ret; 2425 } 2426 2427 ret = opal_new_user_passwd(dev, sess, user_id, &new_key); 2428 if (ret) { 2429 SPDK_ERRLOG("set new passwd error %d\n", ret); 2430 } 2431 2432 ret += opal_end_session(dev, sess, dev->comid); 2433 if (ret) { 2434 SPDK_ERRLOG("end session error %d\n", ret); 2435 } 2436 2437 free(sess); 2438 return ret; 2439 } 2440 2441 int 2442 spdk_opal_cmd_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id, 2443 enum spdk_opal_locking_range locking_range_id, const char *password) 2444 { 2445 struct opal_session *sess; 2446 struct spdk_opal_key opal_key = {}; 2447 int ret; 2448 2449 assert(dev != NULL); 2450 2451 ret = opal_init_key(&opal_key, password); 2452 if (ret != 0) { 2453 return ret; 2454 } 2455 2456 sess = opal_alloc_session(dev); 2457 if (!sess) { 2458 return -ENOMEM; 2459 } 2460 2461 ret = opal_start_auth_session(dev, sess, user_id, &opal_key); 2462 if (ret) { 2463 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2464 free(sess); 2465 return ret; 2466 } 2467 2468 ret = opal_erase_locking_range(dev, sess, locking_range_id); 2469 if (ret) { 2470 SPDK_ERRLOG("get active key error %d\n", ret); 2471 } 2472 2473 ret += opal_end_session(dev, sess, dev->comid); 2474 if (ret) { 2475 SPDK_ERRLOG("end session error %d\n", ret); 2476 } 2477 2478 free(sess); 2479 return ret; 2480 } 2481 2482 int 2483 spdk_opal_cmd_secure_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id, 2484 enum spdk_opal_locking_range locking_range_id, const char *password) 2485 { 2486 struct opal_session *sess; 2487 struct spdk_opal_key opal_key = {}; 2488 struct spdk_opal_key *active_key; 2489 int ret; 2490 2491 assert(dev != NULL); 2492 2493 ret = opal_init_key(&opal_key, password); 2494 if (ret != 0) { 2495 return ret; 2496 } 2497 2498 active_key = calloc(1, sizeof(*active_key)); 2499 if (!active_key) { 2500 return -ENOMEM; 2501 } 2502 2503 sess = opal_alloc_session(dev); 2504 if (!sess) { 2505 free(active_key); 2506 return -ENOMEM; 2507 } 2508 2509 ret = opal_start_auth_session(dev, sess, user_id, &opal_key); 2510 if (ret) { 2511 SPDK_ERRLOG("start authenticate session error %d\n", ret); 2512 free(active_key); 2513 free(sess); 2514 return ret; 2515 } 2516 2517 ret = opal_get_active_key(dev, sess, locking_range_id, active_key); 2518 if (ret) { 2519 SPDK_ERRLOG("get active key error %d\n", ret); 2520 goto end; 2521 } 2522 2523 ret = opal_gen_new_active_key(dev, sess, active_key); 2524 if (ret) { 2525 SPDK_ERRLOG("generate new active key error %d\n", ret); 2526 goto end; 2527 } 2528 memset(active_key, 0, sizeof(struct spdk_opal_key)); 2529 2530 end: 2531 ret += opal_end_session(dev, sess, dev->comid); 2532 if (ret) { 2533 SPDK_ERRLOG("end session error %d\n", ret); 2534 } 2535 free(active_key); 2536 free(sess); 2537 return ret; 2538 } 2539 2540 struct spdk_opal_d0_features_info * 2541 spdk_opal_get_d0_features_info(struct spdk_opal_dev *dev) 2542 { 2543 return &dev->feat_info; 2544 } 2545 2546 struct spdk_opal_locking_range_info * 2547 spdk_opal_get_locking_range_info(struct spdk_opal_dev *dev, enum spdk_opal_locking_range id) 2548 { 2549 assert(id < SPDK_OPAL_MAX_LOCKING_RANGE); 2550 return &dev->locking_ranges[id]; 2551 } 2552 2553 void 2554 spdk_opal_free_locking_range_info(struct spdk_opal_dev *dev, enum spdk_opal_locking_range id) 2555 { 2556 struct spdk_opal_locking_range_info *info; 2557 2558 assert(id < SPDK_OPAL_MAX_LOCKING_RANGE); 2559 info = &dev->locking_ranges[id]; 2560 memset(info, 0, sizeof(*info)); 2561 } 2562 2563 /* Log component for opal submodule */ 2564 SPDK_LOG_REGISTER_COMPONENT(opal) 2565