// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

enclave {
    from "sgx_backtrace.edl" import *;
    from "sgx_env.edl" import *;
    from "sgx_fd.edl" import *;
    from "sgx_fs.edl" import *;
    from "sgx_net.edl" import *;
    from "sgx_stdio.edl" import *;
    from "sgx_sys.edl" import *;
    from "sgx_thread.edl" import *;
    from "sgx_time.edl" import *;
    from "sgx_tprotected_fs.edl" import *;
    from "sgx_tstd.edl" import *;
    from "sgx_tstdc.edl" import *;

    trusted {
        public uint32_t ecall_ipc_entry_point(uint32_t cmd,
                                              [in, size=in_len] const uint8_t* in_buf,
                                              size_t in_len,
                                              [out, size=out_maxlen] uint8_t* out_buf,
                                              size_t out_maxlen,
                                              [out] size_t *real_out_len);
    };

    include "sgx_quote.h"
    untrusted {
        sgx_status_t ocall_sgx_init_quote([out] sgx_att_key_id_t *p_att_key_id,
                                          [out] sgx_target_info_t *p_target_info);

        sgx_status_t ocall_sgx_get_quote_size([in] sgx_att_key_id_t *p_att_key_id,
                                              [out] uint32_t *p_quote_size);

        sgx_status_t ocall_sgx_get_quote([in] sgx_report_t *p_report,
                                         [in] sgx_att_key_id_t *p_att_key_id,
                                         [in, out] sgx_qe_report_info_t *p_qe_report_info,
                                         [out, size=quote_size] uint8_t *p_quote,
                                         uint32_t quote_size);
    };
};
