/*- * BSD LICENSE * * Copyright (c) Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SPDK_OPAL_INTERNAL_H #define SPDK_OPAL_INTERNAL_H #include "spdk/opal_spec.h" #include "spdk/opal.h" #include "spdk/scsi_spec.h" #define IO_BUFFER_LENGTH 2048 #define MAX_TOKS 64 #define OPAL_KEY_MAX 256 #define OPAL_UID_LENGTH 8 #define OPAL_MAX_LRS 8 /* minimum 8 defined by spec */ #define SPDK_OPAL_TPER_TIMEOUT 30 /* seconds */ #define GENERIC_HOST_SESSION_NUM 0x69 #define OPAL_INVAL_PARAM 12 #define SPDK_DTAERROR_NO_METHOD_STATUS 0x89 enum opal_token_type { OPAL_DTA_TOKENID_BYTESTRING = 0xE0, OPAL_DTA_TOKENID_SINT = 0xE1, OPAL_DTA_TOKENID_UINT = 0xE2, OPAL_DTA_TOKENID_TOKEN = 0xE3, /* actual token is returned */ OPAL_DTA_TOKENID_INVALID = 0X0, }; enum opal_atom_width { OPAL_WIDTH_TINY, /* 1 byte in length */ OPAL_WIDTH_SHORT, /* a 1-byte header and contain up to 15 bytes of data */ OPAL_WIDTH_MEDIUM, /* a 2-byte header and contain up to 2047 bytes of data */ OPAL_WIDTH_LONG, /* a 4-byte header and which contain up to 16,777,215 bytes of data */ OPAL_WIDTH_TOKEN }; enum opal_uid_enum { /* users */ UID_SMUID, UID_THISSP, UID_ADMINSP, UID_LOCKINGSP, UID_ANYBODY, UID_SID, UID_ADMIN1, UID_USER1, UID_USER2, /* tables */ UID_LOCKINGRANGE_GLOBAL, UID_LOCKINGRANGE_ACE_RDLOCKED, UID_LOCKINGRANGE_ACE_WRLOCKED, UID_MBRCONTROL, UID_MBR, UID_AUTHORITY_TABLE, UID_C_PIN_TABLE, UID_LOCKING_INFO_TABLE, UID_PSID, /* C_PIN_TABLE object ID's */ UID_C_PIN_MSID, UID_C_PIN_SID, UID_C_PIN_ADMIN1, UID_C_PIN_USER1, /* half UID's (only first 4 bytes used) */ UID_HALF_AUTHORITY_OBJ_REF, UID_HALF_BOOLEAN_ACE, }; /* enum for indexing the spdk_opal_method array */ enum opal_method_enum { PROPERTIES_METHOD, STARTSESSION_METHOD, REVERT_METHOD, ACTIVATE_METHOD, NEXT_METHOD, GETACL_METHOD, GENKEY_METHOD, REVERTSP_METHOD, GET_METHOD, SET_METHOD, AUTHENTICATE_METHOD, RANDOM_METHOD, }; union spdk_discovery0_features { struct spdk_d0_tper_features tper; struct spdk_d0_locking_features locking; struct spdk_d0_geo_features geometry; struct spdk_d0_datastore_features datastore; struct spdk_d0_sum sumode; struct spdk_d0_opal_v200 opalv200; struct spdk_d0_opal_v100 opalv100; }; struct spdk_opal_session { uint32_t sum; /* single user mode */ uint32_t who; struct spdk_opal_key *opal_key; }; struct spdk_opal_lock_unlock { struct spdk_opal_session session; uint32_t l_state; }; struct spdk_opal_new_pw { struct spdk_opal_session session_start; struct spdk_opal_session new_user_pw; }; static const uint8_t spdk_opal_uid[][OPAL_UID_LENGTH] = { /* users */ [UID_SMUID] = /* Session Manager UID */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }, [UID_THISSP] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, [UID_ADMINSP] = { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x01 }, [UID_LOCKINGSP] = { 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x02 }, [UID_ANYBODY] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01 }, [UID_SID] = /* Security Identifier UID */ { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06 }, [UID_ADMIN1] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01 }, [UID_USER1] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x01 }, [UID_USER2] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, 0x02 }, /* tables */ [UID_LOCKINGRANGE_GLOBAL] = { 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 }, [UID_LOCKINGRANGE_ACE_RDLOCKED] = { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE0, 0x01 }, [UID_LOCKINGRANGE_ACE_WRLOCKED] = { 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xE8, 0x01 }, [UID_MBRCONTROL] = { 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x01 }, [UID_MBR] = { 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00 }, [UID_AUTHORITY_TABLE] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00}, [UID_C_PIN_TABLE] = { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00}, [UID_LOCKING_INFO_TABLE] = { 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01 }, [UID_PSID] = { 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0xff, 0x01 }, /* C_PIN_TABLE object ID's */ [UID_C_PIN_MSID] = { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x84, 0x02}, [UID_C_PIN_SID] = { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01}, [UID_C_PIN_ADMIN1] = { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x01, 0x00, 0x01}, [UID_C_PIN_USER1] = { 0x00, 0x00, 0x00, 0x0B, 0x00, 0x03, 0x00, 0x01}, /* half UID's (only first 4 bytes used) */ [UID_HALF_AUTHORITY_OBJ_REF] = { 0x00, 0x00, 0x0C, 0x05, 0xff, 0xff, 0xff, 0xff }, [UID_HALF_BOOLEAN_ACE] = { 0x00, 0x00, 0x04, 0x0E, 0xff, 0xff, 0xff, 0xff }, }; /* * TCG Storage SSC Methods. */ static const uint8_t spdk_opal_method[][OPAL_UID_LENGTH] = { [PROPERTIES_METHOD] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01 }, [STARTSESSION_METHOD] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02 }, [REVERT_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x02 }, [ACTIVATE_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x03 }, [NEXT_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08 }, [GETACL_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d }, [GENKEY_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10 }, [REVERTSP_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11 }, [GET_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16 }, [SET_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x17 }, [AUTHENTICATE_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c }, [RANDOM_METHOD] = { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 }, }; enum spdk_opal_user { OPAL_ADMIN1 = 0x0, OPAL_USER1 = 0x01, OPAL_USER2 = 0x02, OPAL_USER3 = 0x03, OPAL_USER4 = 0x04, OPAL_USER5 = 0x05, OPAL_USER6 = 0x06, OPAL_USER7 = 0x07, OPAL_USER8 = 0x08, OPAL_USER9 = 0x09, }; /* * Response token */ struct spdk_opal_resp_token { const uint8_t *pos; uint8_t _padding[7]; union { uint64_t unsigned_num; int64_t signed_num; } stored; size_t len; /* header + data */ enum opal_token_type type; enum opal_atom_width width; }; struct spdk_opal_resp_parsed { int num; struct spdk_opal_resp_token resp_tokens[MAX_TOKS]; }; struct spdk_opal_step { int (*opal_fn)(struct spdk_opal_dev *dev, void *data); void *data; }; struct spdk_opal_key { uint8_t locking_range; uint8_t key_len; uint8_t _padding[6]; uint8_t key[OPAL_KEY_MAX]; }; struct spdk_opal_locking_range_activate { struct spdk_opal_key key; uint32_t sum; /* single user mode */ uint8_t lockingrange_num; uint8_t lockingrange[OPAL_MAX_LRS]; }; struct spdk_opal_locking_range_setup { uint8_t id; uint8_t _padding[7]; uint64_t range_start; uint64_t range_length; bool RLE; /* Read Lock enabled */ bool WLE; /* Write Lock Enabled */ struct spdk_opal_session session; }; /* header of a response */ struct spdk_opal_header { struct spdk_opal_compacket com_packet; struct spdk_opal_packet packet; struct spdk_opal_data_subpacket sub_packet; }; struct spdk_opal_dev { bool supported; void *dev_handler; const struct spdk_opal_step *steps; uint16_t comid; uint32_t hsn; uint32_t tsn; uint64_t align; uint64_t lowest_lba; size_t cmd_pos; uint8_t cmd[IO_BUFFER_LENGTH]; uint8_t resp[IO_BUFFER_LENGTH]; struct spdk_opal_resp_parsed parsed_resp; size_t prev_d_len; void *prev_data; struct spdk_opal_key *dev_key; struct spdk_opal_info *opal_info; uint64_t timeout; /* seconds */ pthread_mutex_t mutex_lock; /* some structs are accessed by current thread only */ }; enum opal_lock_state { OPAL_LS_DISALBELOCKING = 0x00, OPAL_LS_READLOCK_ENABLE = 0x01, OPAL_LS_WRITELOCK_ENABLE = 0x02, OPAL_LS_RWLOCK_ENABLE = 0x04, }; #endif