// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.kms;

using fuchsia.mem as mem;

const uint8 MAX_KEY_NAME_SIZE = 32;
const uint32 MAX_DATA_SIZE = 65536;

enum Error {
    /// Internal unexpected error.
    INTERNAL_ERROR = 1;
    /// When trying to create/import a new key but a key with the same name already exists.
    KEY_ALREADY_EXISTS = 2;
    /// When the key you are trying to use is not found.
    KEY_NOT_FOUND = 3;
    /// When the key material could not be parsed.
    PARSE_KEY_ERROR = 4;
    /// When the size for input data is larger than `MAX_DATA_SIZE`.
    INPUT_TOO_LARGE = 5;
};

enum AsymmetricKeyAlgorithm {
    RSA_SSA_PSS_SHA256_2048 = 1;
    RSA_SSA_PSS_SHA256_3072 = 2;
    RSA_SSA_PSS_SHA512_4096 = 3;
    RSA_SSA_PKCS1_SHA256_2048 = 4;
    RSA_SSA_PKCS1_SHA256_3072 = 5;
    RSA_SSA_PKCS1_SHA512_4096 = 6;
    ECDSA_SHA256_P256 = 7;
    ECDSA_SHA512_P384 = 8;
    ECDSA_SHA512_P521 = 9;
};

enum KeyOrigin {
    /// The key was generated in this KMS instance.
    GENERATED = 1;
    /// The key was imported.
    IMPORTED = 2;
};

enum KeyProvider {
    /// A mock provider only used for unit testing.
    MOCK_PROVIDER = 1;
    /// A software provider that uses rust AesGcm trait for symmetric key operation and mundane for
    /// asymmetric key operation.
    SOFTWARE_PROVIDER = 2;
    /// A software provider that only supports mundane-based asymmetric key operation.
    SOFTWARE_ASYMMETRIC_ONLY_PROVIDER = 3;
    /// A crypto provider based on Keysafe Trusted App in OPTEE.
    OPTEE_PROVIDER = 4;
};

struct Signature {
    bytes:512 bytes;
};

struct PublicKey {
    bytes:256 bytes;
};

[Discoverable]
protocol KeyManager {
    /// Seal data to an encrypted form.
    ///
    /// Seal data to an encrypted form. The sealed data can only be unsealed by the same KMS instance
    /// by using UnsealData. `plain_text` needs to be less than `MAX_DATA_SIZE` bytes.
    SealData(mem.Buffer plain_text) -> (mem.Buffer cipher_text) error Error;

    /// Unseal sealed data.
    ///
    /// Unseal data previously sealed by this KMS instance.
    UnsealData(mem.Buffer cipher_text) -> (mem.Buffer plain_text) error Error;

    /// Generate an asymmetric key.
    ///
    /// Generate an asymmetric key using `key_name` as the unique name. `key` is the generated
    /// asymmetric key interface request. If the `key_name` is not unique, you would get
    /// `KEY_ALREADY_EXISTS`. The generated key can be used to sign data. The algorithm used for
    /// generating asymmetric key is `ECDSA_SHA512_P521`.
    GenerateAsymmetricKey(
        string:MAX_KEY_NAME_SIZE key_name,
        request<AsymmetricPrivateKey> key) -> () error Error;

    /// Generate an asymmetric key with a specific algorithm.
    ///
    /// Generate an asymmetric key using `key_name` as the unique name and `key_algorithm` as
    /// algorithm. `key` is the generated asymmetric key interface request. If the `key_name` is not
    /// unique, you would get `KEY_ALREADY_EXISTS`.
    GenerateAsymmetricKeyWithAlgorithm(
        string:MAX_KEY_NAME_SIZE key_name,
        AsymmetricKeyAlgorithm key_algorithm,
        request<AsymmetricPrivateKey> key) -> () error Error;

    /// Import an asymmetric private key with a specific algorithm.
    ///
    /// Import an asymmetric private key using `key_name` as the unique name, `key_algorithm` as
    /// algorithm and `data` as key data. `key` is imported asymmetric key interface request. Key
    /// data should be in asn.1 encoded DER format. If the `key_name` is not unique, you would get
    /// `KEY_ALREADY_EXISTS`.
    ImportAsymmetricPrivateKey(
        bytes data,
        string:MAX_KEY_NAME_SIZE key_name,
        AsymmetricKeyAlgorithm key_algorithm,
        request<AsymmetricPrivateKey> key) -> () error Error;

    /// Get an asymmetric private key handle.
    ///
    /// Get an asymmetric private key handle using the `key_name`. If such key is not found, would
    /// return `KEY_NOT_FOUND`.
    GetAsymmetricPrivateKey(
        string:MAX_KEY_NAME_SIZE key_name,
        request<AsymmetricPrivateKey> key) -> () error Error;

    /// Delete a key.
    ///
    /// Delete a key for `key_name`.  For all the current handle to the deleted key, they would
    /// become invalid and all following requests on those handles would return `KEY_NOT_FOUND`, user
    /// should close the invalid handles once get `KEY_NOT_FOUND` error.
    DeleteKey(string:MAX_KEY_NAME_SIZE key_name) -> () error Error;
};

protocol Key {
    /// Get the key origin (generated/imported).
    GetKeyOrigin() -> (KeyOrigin key_origin) error Error;

    /// Get the name for the crypto provider backing up the key.
    GetKeyProvider() -> (KeyProvider key_provider) error Error;
};

protocol AsymmetricPrivateKey {
    compose Key;

    /// Sign `data` using the current key. `data` needs to be less than `MAX_DATA_SIZE` bytes.
    Sign(mem.Buffer data) -> (Signature signature) error Error;
    /// Get the DER format public key for the current private key.
    GetPublicKey() -> (PublicKey public_key) error Error;
    /// Get the key algorithm.
    GetKeyAlgorithm() -> (AsymmetricKeyAlgorithm key_algorithm) error Error;
};
