// 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 Status {
    OK = 0;
    // Internal unexpected error.
    INTERNAL_ERROR = 1;
    // When trying to create/import a new key however another 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;
};

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) -> (Status status, mem.Buffer? cipher_text);

    // Unseal sealed data.
    //
    // Unseal data previously sealed by this KMS instance.
    UnsealData(mem.Buffer cipher_text) -> (Status status, mem.Buffer? plain_text);

    // 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) -> (Status status);

    // 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) -> (Status status);

    // 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) -> (Status status);

    // 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) -> (Status status);

    // 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 Status.
    DeleteKey(string:MAX_KEY_NAME_SIZE key_name) -> (Status status);
};

[FragileBase]
protocol Key {
    // Get the key origin (generated/imported).
    GetKeyOrigin() -> (Status status, KeyOrigin key_origin);
};

protocol AsymmetricPrivateKey {
    compose Key;

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