/*
 * Copyright (C) 2017-2018 Baidu, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Baidu, Inc., nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

enclave {
    from "sgx_stdio.edl" import *;
    from "sgx_backtrace.edl" import *;
    from "sgx_tstdc.edl" import *;

    trusted {
        /* define ECALLs here. */

        public sgx_status_t calc_sha256([in, size=len] const uint8_t* input_str,
                                        size_t len,
                                        [out] uint8_t hash[32]);

        public sgx_status_t aes_gcm_128_encrypt([in] uint8_t key[16],
                                                [in, size=len] const uint8_t* plaintext,
                                                size_t len,
                                                [in] uint8_t iv[12],
                                                [out, size=len] uint8_t* ciphertext,
                                                [out] uint8_t mac[16]);

        public sgx_status_t aes_gcm_128_decrypt([in] uint8_t key[16],
                                                [in, size=len] const uint8_t* ciphertext,
                                                size_t len,
                                                [in] uint8_t iv[12],
                                                [in] uint8_t mac[16],
                                                [out, size=len] uint8_t* plaintext);

        public sgx_status_t aes_cmac([in, size=len] const uint8_t* text,
                                     size_t len,
                                     [in] uint8_t key[16],
                                     [out] uint8_t cmac[16]);

        public sgx_status_t rsa_key([in, size=len] const uint8_t* text, size_t len);

    };

    untrusted {

    };
};
