// These encryption protobufs are not sent over the network.
// Protobufs are used to define a stable backwards compatible persistent storage format.
// These definitions are used by both PD and TiKV to keep their implementations similar.

syntax = "proto3";
package encryptionpb;

import "gogoproto/gogo.proto";
import "rustproto.proto";

option (gogoproto.sizer_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (rustproto.lite_runtime_all) = true;

option java_package = "org.tikv.kvproto";

// General encryption metadata for any data type.
message EncryptionMeta {
    // ID of the key used to encrypt the data.
    uint64 key_id = 1;
    // Initialization vector (IV) of the data.
    bytes iv = 2;
}

// Information about an encrypted file.
message FileInfo {
    // ID of the key used to encrypt the file.
    uint64 key_id = 1;
    // Initialization vector (IV) of the file.
    bytes iv = 2;
    // Method of encryption algorithm used to encrypted the file.
    EncryptionMethod method = 3;
}

message FileDictionary {
    // A map of file name to file info.
    map<string, FileInfo> files = 1;
}

enum EncryptionMethod {
    UNKNOWN = 0;
    PLAINTEXT = 1;
    AES128_CTR = 2;
    AES192_CTR = 3;
    AES256_CTR = 4;
}

// The key used to encrypt the user data.
message DataKey {
    // A sequence of secret bytes used to encrypt data.
    bytes key = 1;
    // Method of encryption algorithm used to encrypted data.
    EncryptionMethod method = 2;
    // Creation time of the key.
    uint64 creation_time = 3;
    // A flag for the key have ever been exposed.
    bool was_exposed = 4;
}

message KeyDictionary {
    // A map of key ID to dat key.
    map<uint64, DataKey> keys = 1;
    // ID of a key currently in use.
    uint64 current_key_id = 2;
}

// Master key config.
message MasterKey {
    oneof backend {
        MasterKeyPlaintext plaintext = 1;
        MasterKeyFile file = 2;
        MasterKeyKms kms = 3;
    }
}

// MasterKeyPlaintext indicates content is stored as plaintext.
message MasterKeyPlaintext {}

// MasterKeyFile is a master key backed by a file containing encryption key in human-readable
// hex format.
message MasterKeyFile {
    // Local file path.
    string path = 1;
}

// MasterKeyKms is a master key backed by KMS service that manages the encryption key,
// and provide API to encrypt and decrypt a data key, which is used to encrypt the content.
message MasterKeyKms {
    // KMS vendor.
    string vendor = 1;
    // KMS key id.
    string key_id = 2;
    // KMS region.
    string region = 3;
    // KMS endpoint. Normally not needed.
    string endpoint = 4;
}

message EncryptedContent {
    // Metadata of the encrypted content.
    // Eg. IV, method and KMS key ID
    // It is preferred to define new fields for extra metadata than using this metadata map.
    map<string, bytes> metadata = 1;
    // Encrypted content.
    bytes content = 2;
    // Master key used to encrypt the content.
    MasterKey master_key = 3;
    // Initilization vector (IV) used.
    bytes iv = 4;
    // Encrypted data key generated by KMS and used to actually encrypt data.
    // Valid only when KMS is used.
    bytes ciphertext_key = 5;
}
