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