Intel® Software Guard Extensions (Intel® SGX)
Discussion board focused on hardware-based isolation and memory encryption to provide extended code protection in solutions.

About SGX ECALLs

刘__高
Beginner
415 Views

In the edl file,

enclave {
    from "sgx_tstdc.edl" import *;
    #include <ippcp.h>
    trusted {
        /* define ECALLs here. */
        public void foo([out]IppsBigNumState* C, [out]IppsBigNumState* Z, [out]IppsRSAPrivateKeyState* pPrv, [out]Ipp8u * scratchBuffer);
    };

    untrusted {
        /* define OCALLs here. */

    };
};
 

This is Enclave.cpp

#include "EnclaveT_t.h"
#include "sgx_trts.h"
#include <ostream>
#include <string.h>
#include <ippcp.h>


void foo(IppsBigNumState* C, IppsBigNumState* Z, IppsRSAPrivateKeyState* pPrv, Ipp8u * scratchBuffer)
{
    
    // de-crypt  message, and return status code for verification
    IppStatus status2;
    status2 = ippsRSA_Decrypt(C, Z, pPrv, scratchBuffer);

}

 

This is App.ccp

// NewencT.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <stdio.h>
#include <tchar.h>
#include "sgx_urts.h"
#include <string.h>
#include "EnclaveT_u.h"
#include "ippcp.h"
#include <iostream>
#include <xsample_bignum.h>
#include <BigNumber.h>
using namespace std;


#define ENCLAVE_FILE _T("EnclaveT.signed.dll")
#define MAX_BUF_LEN 100

static IppsBigNumState* newBN(int len, const Ipp32u* pData)
{
    int size;
    ippsBigNumGetSize(len, &size);
    IppsBigNumState* pBN = (IppsBigNumState*)(new Ipp8u[size]);
    ippsBigNumInit(len, pBN);
    if (pData)
        ippsSet_BN(IppsBigNumPOS, len, pData, pBN);
    return pBN;
}

IppsPRNGState* newPRNG(void)
{
    int ctxSize;
    ippsPRNGGetSize(&ctxSize);
    IppsPRNGState* pCtx = (IppsPRNGState*)(new Ipp8u[ctxSize]);
    ippsPRNGInit(160, pCtx);
    return pCtx;
}

// Prime Generator context
//
IppsPrimeState* newPrimeGen(int maxBits)
{
    int size;
    ippsPrimeGetSize(maxBits, &size);
    IppsPrimeState* pCtx = (IppsPrimeState*)(new Ipp8u[size]);
    ippsPrimeInit(maxBits, pCtx);
    return pCtx;
}


void deletePrimeGen(IppsPrimeState* pPrimeG)
{
    delete[](Ipp8u*)pPrimeG;
}

void deletePRNG(IppsPRNGState* pPRNG)
{
    delete[](Ipp8u*)pPRNG;
}

int main()
{
    // specify the context of key components to contain generated key // data
    IppsBigNumState* pModulus = newBN(1024 / 32, NULL);
    IppsBigNumState* pPublicExp = newBN(1024 / 32, NULL);
    IppsBigNumState* pPrivateExp = newBN(1024 / 32, NULL);
    // (bit) size of key components
    int bitsN = 1024; // Length of RSA system in bits(the modulus. size of                          
                      // our modulus, must be large(4096 standard), but we will 1024

    int bitsE = 512; // Length of the RSA public exponent in bits(the e //component
    int bitsP = 512; //Length in bits of the p factors of the modulus(that //is, the p in the equation: n = p*q
    int bitsQ = 512;//Length in bits of the q factors of the modulus(that //is, the q in the equation: n = p*q

    int keyCtxSize; //Available size of memory buffer being initialized
    // setup public key

    // calculate size of public keys context
    ippsRSA_GetSizePublicKey(bitsN, bitsE, &keyCtxSize);

    //public key context allocated with generated buffer size
    IppsRSAPublicKeyState* pPub = (IppsRSAPublicKeyState*)(new Ipp8u[keyCtxSize]);
    //context initialized in memory
    ippsRSA_InitPublicKey(bitsN, bitsE, pPub, keyCtxSize);

    // setup (type2) private key

    //calculate size of private keys context
    ippsRSA_GetSizePrivateKeyType2(bitsP, bitsQ, &keyCtxSize);
    //private key context allocated with generated buffer size
    IppsRSAPrivateKeyState* pPrv = (IppsRSAPrivateKeyState*)(new Ipp8u[keyCtxSize]);
    //context initialized in memory
    ippsRSA_InitPrivateKeyType2(bitsP, bitsQ, pPrv, keyCtxSize);

    int buffSizePrivate; // create variable to reference retrieved size
    ippsRSA_GetBufferSizePrivateKey(&buffSizePrivate, pPrv); //retrieve //buffer size for private key

    Ipp8u * scratchBuffer = NULL; //initialize scratch buffer as ipp8u //(usigned char equivalent)
    scratchBuffer = new Ipp8u[buffSizePrivate]; //allocate memory for //scratch buffer

    // random generator
    IppsPRNGState* pRand = newPRNG();

    // prime generator
    IppsPrimeState* pPrimeG = newPrimeGen(512);

    int validateRes = IS_VALID_KEY; // IS_VALID_KEY is the success code
    // validate keys
    ippsRSA_ValidateKeys(&validateRes,
        pPub, pPrv, NULL, scratchBuffer,
        10, pPrimeG, ippsPRNGen, pRand);
    // check that success code hasn’t changed, and print message on //successful
    if (IS_VALID_KEY == validateRes) {
        cout << "validation successful \n" << endl;
    }

    // Pointer to IppsBigNumState context for searching an RSA public //exponent
    Ipp32u E = { 0x11 };
    IppsBigNumState* pSrcPublicExp = newBN(1, &E);

    IppStatus status; // reference to generated message code

    // keys generator
    status = ippsRSA_GenerateKeys(pSrcPublicExp, pModulus, pPublicExp, pPrivateExp, pPrv, scratchBuffer, 10, pPrimeG, ippsPRNGen, pRand);

    // check for successful generation of keys
    // ippStsNoErr signals success
    if (status == ippStsNoErr) {
        cout << "keys generation successful \n" << endl;
    }

    // get modulus generated
    BigNumber modN(pModulus); // create BigNumber instance of modulus 
    //modN.tBN("Modulus (n): "); // display key data

    //cout << "\n" << endl; // print empty line

    // get public key generated 
    BigNumber Pk(pPublicExp); // create BigNumber instance of public key
    //Pk.tBN("Public Key Exponent (e): "); // display key data

    //cout << "\n" << endl; // print empty line

    //get private key generated
    BigNumber Pvk(pPrivateExp); //create BigNumber instance of private key
    //Pvk.tBN("Private Key Exponent (d): "); // display key data

    // set public key with generated public key
    ippsRSA_SetPublicKey(pModulus, pPublicExp, pPub);

    // set up type1 private key component with generated private key
    ippsRSA_SetPrivateKeyType1(pModulus, pPrivateExp, pPrv);

    Ipp32u dataM[] = { // plain text to be encrypted
        0x12345678,0xabcde123,0x87654321,
        0x111aaaa2,0xbbbbbbbb,0xcccccccc,
        0x12237777,0x82234587,0x1ef392c9,
        0x43581159,0xb5024121,0xa48D2869,
        0x2abababa,0x1a2b3c22,0xa47728B4,
        0x54321123,0xaaaaaaaa,0xbbbbbbbb,
        0xcccccccc,0xdddddddd,0x34667666,
        0xa46a3aaa,0xe4251e84,0xf31f2Eff,
        0xfec55267,0x11111111,0x98765432,
        0x54376511,0x21323111,0x85433abc,0xcaa44322,0x001234ef};

      //    cout << "DATAM "<< sizeof(dataM) << endl;
    
    // we will create ciphertext context with size of dataN
    Ipp32u dataN[] = { // data for ciphertext context creation
            0x03cccb37,0x6acadded,0xdf4f20d0,0x2458257d,
            0xda3b7886,0x5c1b1a4c,0xea6f676b,0x59f51e09,
            0xc0691195,0x8076c61f,0x4221d059,0xd021673a,
            0x139bd5ef,0x95189046,0x10eb90ea,0x127af4e5,
            0x14f5dcb8,0x1e13510f,0x6e2e0558,0xa650fce0,
            0xff0bcd51,0xe218e43d,0xad045536,0xdc4a21d7,
            0x74edee68,0xb474ad57,0x79514004,0xa65a27a3,
            0x9e5259c1,0xe78e89eb,0xb34ed292,0x99197f0d };

    // create contexts for  message and ciphertext, this allocate the //appropriate memory size for storing message and ciphertext

    // create message context
    IppsBigNumState* Msg = newBN(sizeof(dataM) / sizeof(dataM[0]), dataM);
    //create ciphertext context
    IppsBigNumState* C = newBN(sizeof(dataN) / sizeof(dataN[0]), dataN);


    // encrypt  message, and return status code for verification
    IppStatus status1;
    status1 = ippsRSA_Encrypt(Msg, C, pPub, scratchBuffer);

    // check for successful encryption of msg
    if (status1 == ippStsNoErr) {
        cout << "message encryption successful \n" << endl;
    }

    //// de-crypt  message, and return status code for verification
    //IppStatus status2;
    //status2 = ippsRSA_Decrypt(C, Z, pPrv, scratchBuffer);

    //// check for successful decryption of ciphertext
    //if (status2 == ippStsNoErr) {
    //    cout << "message decryption successful \n" << endl;

        sgx_enclave_id_t     eid;
        sgx_status_t        ret = SGX_SUCCESS;
        sgx_launch_token_t    token = { 0 };

        int updated = 0;
        char buffer[MAX_BUF_LEN] = "Hello World!";

        //创建包含token的enclave容器
        ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
        if (ret != SGX_SUCCESS)
        {
            printf("APP:error %#x ,failed to create enclave .\n", ret);
            return -1;
        }

        // create de-ciphertext context
        IppsBigNumState* Z = newBN(sizeof(dataN) / sizeof(dataN[0]), dataN);

        foo(eid, C, Z, pPrv, scratchBuffer);
    
        
        //// create de-ciphertext context
        //IppsBigNumState* Z = newBN(sizeof(dataN) / sizeof(dataN[0]), dataN);

        //// de-crypt  message, and return status code for verification
        //IppStatus status2;
        //status2 = ippsRSA_Decrypt(C, Z, pPrv, scratchBuffer);

    
    cout << "YIKU" << endl;
    

    ////Enclave CALL(ECALL) 启动enclave容器
    //foo(0);
    //printf("successfully");
    //getchar();

    //销毁enclave容器
    if (SGX_SUCCESS != sgx_destroy_enclave(eid))
        return -1;
    system("pause");
    getchar();
    return 0;

}
 

When I rebuild the enclave project, I get the error "  D:\project\EnclaveT\EnclaveT\EnclaveT.edl(246,7): parse error ". 

Could you tell how to solve this problem? I guess the big problem appears in the edl file, but I don't know how to deal with it. 

0 Kudos
1 Reply
JesusG_Intel
Moderator
415 Views

Hello, 

In the EDL file, remove the "#" from #include <ippcp.h>. See page 61 of the Intel Software Guard Extensions SDK Developer Reference for Windows OS for more guidance on Enclave Definition Syntax.

Regards,

Jesus 

0 Kudos
Reply