// 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 MAX_KEY_NAME_SIZE uint8 = 32;
const MAX_DATA_SIZE uint32 = 65536;

type Error = strict enum {
    /// 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;
};

type AsymmetricKeyAlgorithm = strict enum {
    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;
};

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

type KeyProvider = strict enum {
    /// 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;
};

type Signature = struct {
    bytes bytes:512;
};

type PublicKey = struct {
    bytes bytes:256;
};

@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(resource struct {
        plain_text mem.Buffer;
    }) -> (resource struct {
        cipher_text mem.Buffer;
    }) error Error;

    /// Unseal sealed data.
    ///
    /// Unseal data previously sealed by this KMS instance.
    UnsealData(resource struct {
        cipher_text mem.Buffer;
    }) -> (resource struct {
        plain_text mem.Buffer;
    }) 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(resource struct {
        key_name string:MAX_KEY_NAME_SIZE;
        key server_end:AsymmetricPrivateKey;
    }) -> (struct {}) 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(resource struct {
        key_name string:MAX_KEY_NAME_SIZE;
        key_algorithm AsymmetricKeyAlgorithm;
        key server_end:AsymmetricPrivateKey;
    }) -> (struct {}) 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(resource struct {
        data bytes;
        key_name string:MAX_KEY_NAME_SIZE;
        key_algorithm AsymmetricKeyAlgorithm;
        key server_end:AsymmetricPrivateKey;
    }) -> (struct {}) 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(resource struct {
        key_name string:MAX_KEY_NAME_SIZE;
        key server_end:AsymmetricPrivateKey;
    }) -> (struct {}) 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(struct {
        key_name string:MAX_KEY_NAME_SIZE;
    }) -> (struct {}) error Error;
};

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

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

protocol AsymmetricPrivateKey {
    compose Key;

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