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