/** * Copyright 2013-2015 Seagate Technology LLC. * * This Source Code Form is subject to the terms of the Mozilla * Public License, v. 2.0. If a copy of the MPL was not * distributed with this file, You can obtain one at * https://mozilla.org/MP:/2.0/. * * This program is distributed in the hope that it will be useful, * but is provided AS-IS, WITHOUT ANY WARRANTY; including without * the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or * FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public * License for more details. * * See www.openkinetic.org for more project information */ package com.seagate.kinetic.proto; option java_outer_classname = "Kinetic"; // this is a local message to allow the program to read // the protocol version number by building this message // and then reading the value. message Local { optional string protocolVersion = 1 [default = "3.1.0"]; } // THe message is an authorization and command bytes. message Message { // 1-3 are reserved, do not u // Every message must be one of the following types. optional AuthType authType = 4; // Normal messages optional HMACauth hmacAuth = 5; // for Pin based operations. These include device unlock and // device erase optional PINauth pinAuth = 6; // the embedded message providing the request (for HMACauth) and // the response (for all auth types). optional bytes commandBytes = 7; // The Message Type determines how the the message is to be processed. enum AuthType { // if the message type is unknown, close the connection INVALID_AUTH_TYPE = -1; // This is for normal traffic. Check the HMAC of the command and // if correct, process the command. HMACAUTH = 1; // device unlock and ISE command. These must come over the TLS connection. // If they do not, close the connection. If it is over // the TLS connection, execute the pin operation. PINAUTH = 2; // In the event that the device is going to close the connection, an // unsolicited status will be returned first. UNSOLICITEDSTATUS = 3; } // This is for normal message to the device // and for responses. These are allowed once the // device is unlocked. The HMAC provides for // authenticity, Integrity and to enforce roles. message HMACauth { // The "identity" identifies the requester and the key and algorithm to // be used for hmac. optional int64 identity = 1; optional bytes hmac = 2; } // Pin based authentication for Pin operations. message PINauth { // The pin necessary to make the operations valid optional bytes pin = 1; } } message Command { //message header optional Header header = 1; //message body optional Body body = 2; //operation status optional Status status = 3; //message header message Header { // "cluster" is the number of the cluster definition. If this is incompatible, // the request is rejected. If it is missing, it is assumed to be 0. (0 allows systems not // using cluster versioning to ignore this field in the header and in the setup.) optional int64 clusterVersion = 1; // 2 is reserved. // A unique number for this connection between the source and target. On the first request // to the device, this should be the time of day in seconds since 1970. The device can change this // number and the client must continue to use the new number and the number must remain // constant during the session. (See security document). optional int64 connectionID = 3; // the sequence of this request in this TCP connection. As long as this value is getting larger we have // strong ordering and replay prevention within a session. This combined with the time and connectionID // provides strong ordering between sessions. (See security document). optional int64 sequence = 4; //co-related sequence optional int64 ackSequence = 6; //operation code - put/get/delete/GetLog, etc. optional MessageType messageType = 7; // 8 is reserved, no not use // Request timeout (in ms). This is the amount of time that this request should take. If this timeout // is triggered, there are three possible results that can be returned. // - SERVICE_BUSY meaning that the request was still on the queue waiting to be executed // - EXPIRED meaning that a long running operation was stopped because the time expired. // - DATA_ERROR meaning that the request was in process, but that the error recovery was not // complete at the time that the time expired optional int64 timeout = 9; // If true, requests will not attempt multi revolution recoveries even if the timeout has not occurred. // In this case the result will be DATA_ERROR. To have the device exhaust all possible error recovery, leave // this field off or set to false, and make sure that the timeout is set to be longer than any possible queue // time and error recovery time. On a disk device, the maximum error recovery time could be seconds. // Once all possible data recovery operations are complete and have not succeeded, PERM_DATA_ERROR will be // returned. optional bool earlyExit = 10; // 11 is reserved // Priority is a simple integer that determines the priority of this // request. All activity at a higher priority will execute before that // of lower priority traffic. A higher number is higher priority. optional Priority priority = 12; // A hint of how long a job should run before yielding. Specified in // miliseconds. A value of 0 indicates that the operation can perform one // sub operation and then check to see if there are other sub higher // priority operations. An example of a sub-operation might be a single put // in a P2P operation, etc. optional int64 TimeQuanta = 13; // batch id to be included in each command of a batch operation // this id is generated by client library and must be unique // within the same connection. optional uint32 batchID = 14; } //message body message Body { //key/value op optional KeyValue keyValue = 1; //range operation optional Range range = 2; //set up operation optional Setup setup = 3; // Peer to Peer operations. optional P2POperation p2pOperation = 4; // 5 is reserved. //GetLog optional GetLog getLog = 6; //set up security optional Security security = 7; // Perform Pin-based operations optional PinOperation pinOp = 8; // batch operation // This is included in the END_BATCH and END_BATCH_RESPONSE. optional Batch batch = 9; // power management optional PowerManagement power = 10; } message PowerManagement { optional PowerLevel level = 1; } // This is included in the END_BATCH and END_BATCH_RESPONSE. message Batch { // set by the client library in END_BATCH request message. // the total number of operations in the batch optional int32 count = 1; // set by the drive in END_BATCH_RESPONSE message. // If a batch is committed successfully, all sequence Ids of those // commands (PUT/DELETE) performed in the batch are // added in the END_BATCH_RESPONSE message. repeated int64 sequence = 2 [packed=true]; // This field is set by the drive if a batch commit failed. // The first failed operation sequence in the batch is set as value. optional int64 failedSequence = 3; } //operation status message Status { //status code optional StatusCode code = 1; //status message optional string statusMessage = 2; //optional information comes with status optional bytes detailedMessage = 3; //enum of status code enum StatusCode { // Must come first, so default is invalid INVALID_STATUS_CODE = -1; // for a P2P operation, there was a reason the list was incomplete. This is for items // that were not attempted. NOT_ATTEMPTED = 0; SUCCESS = 1; HMAC_FAILURE = 2; NOT_AUTHORIZED = 3; VERSION_FAILURE = 4; INTERNAL_ERROR = 5; HEADER_REQUIRED = 6; NOT_FOUND = 7; VERSION_MISMATCH = 8; // If there are too many requests in the device at this time, requests // will be rejected with this error message. The common response is to // wait and retry the operation with an exponential back-off. SERVICE_BUSY = 9; // A long operation was started and a timeout happened mid operation. This // does not imply a failure. EXPIRED = 10; // A data error happened and either earlyExit was set or the timeout happened. DATA_ERROR = 11; // A data error happened and all possible error recovery operations have been // performed. There is no value to trying this again. If the system has the ability // to determine the correct information, writing the data again can get rid PERM_DATA_ERROR = 12; // A TCP connection to the remote peer failed. This is only for the P2P Operation REMOTE_CONNECTION_ERROR = 13; // When the device is full, it returns this error. The background scrubbing may free space, // so this error may go away NO_SPACE = 14; // In the set security, an HmacAlgorithm was specified as Unknown or there is a protocol // version mis-match NO_SUCH_HMAC_ALGORITHM = 15; // The request is not valid. Subsequent attempts with the same request will return the same code. // Examples: GET does not specify keyValue message, GETKEYRANGE operation does not specify startKey, etc INVALID_REQUEST = 16; // For P2P Requests, the operation was executed successfully but some nested operations // did not succeed. This indicates that callers should review the status of nested operations. // This status should only be used in the Command > Status, not in the Status messages // of nested P2POperations NESTED_OPERATION_ERRORS = 17; // If the device is currently locked and can not validate // the hmac. This is returned as an status // and the connection is terminated. DEVICE_LOCKED = 18; // The device was already unlocked. The validity of the // pin was NOT checked. The connection remains open. DEVICE_ALREADY_UNLOCKED = 19; // The connection is being terminated. Details as to why are // in the message string. CONNECTION_TERMINATED = 20; // During a batch operation, the only operations allowed are put " // and delete. This error is put against the offending command and " // the rest of the commands and the END_BATCH return NOT_ATTEMPTED." INVALID_BATCH = 21; // the status is returned to caller if commands are received when // device is in hibernate state HIBERNATE = 22; // the status is returned to caller if commands are received when // device is shutting down. SHUTDOWN = 23; } } //key/value entry operation message KeyValue { // 1 is reserved // On a put or delete, this is the next version that the data will be. The version field is opaque to the // target. (See Atomic operations document) optional bytes newVersion = 2; // On a put or delete, this forces the write to ignore the existing version of existing data (if it exists). optional bool force = 8; //entry key optional bytes key = 3; //entry version in store optional bytes dbVersion = 4; // this is the integrity value of the data. This may or may not be in the clear, depending on the algorithm // used. optional bytes tag = 5; // The following is for the protection of the data. If the data is protected with a hash or CRC, then // the algorithm will be negative. If the data protection algorithm is not a standard unkeyed algorithm // then a positive number is used and the device has no idea what the key is. See the discussion of // encrypted key/value store.(See security document). optional Algorithm algorithm = 6; // for read operations, this will get all the information about the value except for the // value itself. This is valuable for getting the integrity field or the version without also // having to get the data. If this field is not present, it is as if it is false. For // write or delete operations, if this is set, the command is rejected. optional bool metadataOnly = 7; // Synchronization allows the puts and deletes to determine if they are to be // WRITETHROUGH: This request is made persistent before returning. This does not effect any other pending operations. // WRITEBACK: They can be made persistent when the device chooses, or when a subsequent FLUSH is give to the device. // FLUSH: All pending information that has not been written is pushed to the disk and the command that // specifies FLUSH is written last and then returned. All WRITEBACK writes that have received ending // status will be guaranteed to be written before the FLUSH operation is returned completed. optional Synchronization synchronization = 9; } enum Synchronization { INVALID_SYNCHRONIZATION = -1; // Must come first, so default is invalid WRITETHROUGH = 1; WRITEBACK = 2; FLUSH = 3; } //key range op message Range { optional bytes startKey = 1; optional bytes endKey = 2; optional bool startKeyInclusive = 3; optional bool endKeyInclusive = 4; // The maximum number of keys returned optional int32 maxReturned = 5; // The keys are searched for and returned in a reverse order. For instance // if the search is startKey="j", endKey="k", maxReturned=2, // reverse=true and the keys "k0", "k1", "k2" exist // the system will return "k2" and "k1" in that order. optional bool reverse = 6; // 7 is reserved; //get range response . repeated bytes keys = 8; } //set up operation. // if any or all of these are fields are included, they are set. // These are persistent options that are retained across power fail and // erased on either PIN erase or PIN secure erase. message Setup { // The cluster version to be checked. The default if never set is 0. // If this is missing, it is assumed to be unchanged; // This is persistent between boots of the device. optional int64 newClusterVersion = 1; // 2, 3, 4 are reserved. // indicates the presence of a firmware load in the data portion of this // message. The firmware is itself protected on its own for integrity, // authenticity, etc. optional bool firmwareDownload = 5; } // P2P operations allow devices to be able to send keys to other devices. // this is either a standalone command or added to a put command. message P2POperation { // Describe the target machine optional Peer peer = 1; // List of operations to be performed. repeated Operation operation = 2; // Indicates whether all operations have Status SUCCESS // When false, clients should traverse Operation status codes to discover // error cases. // When true, no further error checking should be required. optional bool allChildOperationsSucceeded = 3; message Operation { // 1 and 2 are reserved // the key of the entry to move optional bytes key = 3; // the expected version number in the other machine // the version number will be the version in the stored entry. optional bytes version = 4; // to have the moved key have a different final key used. optional bytes newKey = 5; // force the write ignoring the current key version. optional bool force = 6; // returned status optional Status status = 7; // an operation to add to this put operation. THis allows the // formation of a pipeline client -> A ->B ->C with the status for all returning // back to the client. optional P2POperation p2pop = 8; } message Peer { optional string hostname = 1; optional int32 port = 2; optional bool tls = 3; } } //get log message GetLog { repeated Type types = 1; enum Type { INVALID_TYPE = -1; // Must come first, so default is invalid UTILIZATIONS = 0; TEMPERATURES = 1; CAPACITIES = 2; CONFIGURATION = 3; STATISTICS = 4; MESSAGES = 5; LIMITS = 6; DEVICE = 7; } repeated Utilization utilizations = 2; repeated Temperature temperatures = 3; optional Capacity capacity = 4; optional Configuration configuration = 5; repeated Statistics statistics = 6; optional bytes messages = 7; optional Limits limits = 8; optional Device device = 9; message Utilization { // The name of the utilization being reported. These names can be standard and proprietary. The // standard names are "HDA", "EN0" and "EN1". If there are more items that are // being reported, such as processor utilization, can have a descriptive name. optional string name = 1; // A number between 0.00 and 1.00. The resolution of this number is up to the // device. 1 means 100% utilized. optional float value = 2; } message Temperature { // The name of the temperature being reported. These names can be standard and proprietary. The // standard name is "HDA". If there are more items that are // being reported, such as processor temperature, can have a descriptive name. optional string name = 1; // The current temperature in degrees c optional float current = 2; optional float minimum = 3; optional float maximum = 4; optional float target = 5; } // These capacities are in bytes. message Capacity { // 1-3 are reserved optional uint64 nominalCapacityInBytes = 4; optional float portionFull = 5; } message Configuration { // name of the vendor. Should be "Seagate" optional string vendor = 5; // The model of the device. // "Simulator" for the simulator. optional string model = 6; // Device Serial number (SN) optional bytes serialNumber = 7; // Device world wide name (WWN) optional bytes worldWideName = 14; // This is the vendor specific version of the software on the device in dot notation // if this is not set or ends with "x" this is test code. optional string version = 8; optional string compilationDate = 12; optional string sourceHash = 13; // This is the version of the protocol (.proto file) that the device uses. // This is not the highest or lowest version that is supported, just // the version that was compiled. optional string protocolVersion = 15; optional string protocolCompilationDate = 16; optional string protocolSourceHash = 17; // the interfaces for this device. one per interface. repeated Interface interface = 9; // these are the port numbers for the software optional int32 port = 10; optional int32 tlsPort = 11; // The unsolicited message at the beginning of a connection will return // the drive status. The only two possible values are OPERATIONAL // or HIBERNATE. optional PowerLevel currentPowerLevel = 18; // 18, 19 are reserved. message Interface { optional string name = 1; optional bytes MAC = 2; optional bytes ipv4Address = 3; optional bytes ipv6Address = 4; } } // These numbers start at 0 when the device starts up and never wraps or resets. message Statistics { optional MessageType messageType = 1; // 2 and 3 are reserved, do not use optional uint64 count = 4; // This is the sum of the data that is in the data portion. This does not include t // the command description. For P2P operations, this is the amount of data moved between // devices optional uint64 bytes = 5; } message Limits { optional uint32 maxKeySize = 1; optional uint32 maxValueSize = 2; optional uint32 maxVersionSize = 3; optional uint32 maxTagSize = 4; optional uint32 maxConnections = 5; optional uint32 maxOutstandingReadRequests = 6; optional uint32 maxOutstandingWriteRequests = 7; optional uint32 maxMessageSize = 8; optional uint32 maxKeyRangeCount = 9; optional uint32 maxIdentityCount = 10; optional uint32 maxPinSize = 11; optional uint32 maxOperationCountPerBatch = 12; optional uint32 maxBatchCountPerDevice = 13; } // The Device GetLog message is to ask the device to send back the // log of a certain name in the value field. The limit of each // log is 1m byte. // // Proprietary names should be prefaced by the vendor name so that name // collisions do not happen in the future. An example could be names that // start with “com.WD” would be for Western Digital devices. // // If the name is not found, the get log returns NOT_FOUND. // // There can be only one Device in the list of logs that can be retrieved.! message Device { optional bytes name = 1; } } // These are persistent options that are retained across power fail and // erased on either PIN erase or PIN secure erase. message Security { repeated ACL acl = 2; // one per identity // Set the lock and erase pins. optional bytes oldLockPIN = 3; optional bytes newLockPIN = 4; optional bytes oldErasePIN = 5; optional bytes newErasePIN = 6; // message ACL { optional int64 identity = 1; optional bytes key = 2; // the HMAC key optional HMACAlgorithm hmacAlgorithm = 3; // value that must be in the key for read, write, range requests. If none are specified // then no checking occurs. If one or more is specified, one must match or the request // is rejected repeated Scope scope = 4; enum HMACAlgorithm { INVALID_HMAC_ALGORITHM = -1; // Must come first // 0 is reserved; do not use HmacSHA1 = 1; // this is the default } message Scope { optional int64 offset = 1; optional bytes value = 2; repeated Permission permission = 3; // one per role optional bool TlsRequired = 4; // This is only allowed over the the TLS connection } enum Permission { INVALID_PERMISSION = -1; // place holder for backward .proto file compatibility READ = 0; // can read key/values WRITE = 1; // can write key/values DELETE = 2; RANGE = 3; // can do a range SETUP = 4; // can set up and a device P2POP = 5; // can do a peer to peer operation GETLOG = 7; // can get log SECURITY = 8; // can set up the security roles of the device POWER_MANAGEMENT = 9; // can setup power management } // The maxPriority is checked against the header priority and range // priority (if present) fields. The priority must be greater than // or equal to this maxPriority field. optional Priority maxPriority = 5; } } // Pin Operations are used for special commands that are valid when the device // is locked or to be locked. These are unlock, lock and erase. // This must come over the TLS connection to protect the confidentiality and // integrity. This operations must be used with PinAuth. message PinOperation { optional PinOpType pinOpType = 1; enum PinOpType { INVALID_PINOP = -1; // The pin will unlock the device UNLOCK_PINOP = 1; // This will lock the device. This includes all // configuration and user data. This operation is // secure from even given physical access and // disassembly of the device. LOCK_PINOP = 2; // Both erase operations will return // the device to an as manufactured state removing all // user data and configuration settings. // Erase the device. This may be secure // or not. The implication is that it may be faster // than the secure operation. ERASE_PINOP = 3; // Erase the device in a way that will // physical access and disassembly of the device // will not SECURE_ERASE_PINOP = 4; } } enum Priority { NORMAL = 5; LOWEST = 1; LOWER = 3; HIGHER = 7; HIGHEST = 9; } //algorithm enum Algorithm { INVALID_ALGORITHM = -1; // Must come first, so default is invalid SHA1 = 1; // see NIST SHA2 = 2; // see NIST SHA3 = 3; // see NIST. The length of the tag determined the length of the hash CRC32C = 4; CRC64 = 5; CRC32 = 6; // 7-99 are reserved. // 100-inf are private algorithms. } //operation code enum MessageType { INVALID_MESSAGE_TYPE = -1; // Must come first, so default is invalid GET = 2; //get operation GET_RESPONSE = 1; PUT = 4; //put operation PUT_RESPONSE = 3; DELETE = 6; DELETE_RESPONSE = 5; GETNEXT = 8; GETNEXT_RESPONSE = 7; GETPREVIOUS = 10; GETPREVIOUS_RESPONSE = 9; GETKEYRANGE = 12; GETKEYRANGE_RESPONSE = 11; // 13 and 14 are reserved, do not use GETVERSION = 16; GETVERSION_RESPONSE = 15; // 17, 18, 19, and 20 are reserved, do not use SETUP = 22; SETUP_RESPONSE = 21; GETLOG = 24; GETLOG_RESPONSE = 23; SECURITY = 26; SECURITY_RESPONSE = 25; PEER2PEERPUSH = 28; //peer to peer push operation PEER2PEERPUSH_RESPONSE = 27; NOOP = 30; NOOP_RESPONSE = 29; FLUSHALLDATA = 32; FLUSHALLDATA_RESPONSE = 31; // 33, 34 are reserved PINOP = 36; // Pin based operations PINOP_RESPONSE = 35; // Media scan is to check that the user data is readable, and // if the end to end integrity is known to the device, if the // end to end integrity field is correct. MEDIASCAN = 38; MEDIASCAN_RESPONSE = 37; // This performs optimizations of the media. Things like // defragmentation, compaction, garbage collection, compression // could be things accomplished using the media optimize command. MEDIAOPTIMIZE = 40; MEDIAOPTIMIZE_RESPONSE = 39; // batch operations START_BATCH = 42; START_BATCH_RESPONSE = 41; END_BATCH = 44; END_BATCH_RESPONSE = 43; ABORT_BATCH = 46; ABORT_BATCH_RESPONSE = 45; // power management SET_POWER_LEVEL = 48; SET_POWER_LEVEL_RESPONSE = 47; } enum PowerLevel { INVALID_LEVEL = -1; OPERATIONAL = 1; // Fully operational mode, default mode for the drive HIBERNATE = 2; // All operations will be rejected SHUTDOWN = 3; FAIL = 4; } }