Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[Intel SGX] sgx_rijndael128GCM_encrypt/decryptをやってみた。

More than 1 year has passed since last update.

本記事の背景

SGXでrijndael encryptionができるみたいなのでやってみた。
インターネットの海を彷徨っても(英語でも、日本語でも)文献があまり見当たらなかったのでまとめた。

本記事の対象

  • Intel SGXについて知っていること。
  • rijndael(AES)暗号化について知ってること。
  • Enclave.edl/Enclave.cpp/App.cppで何をやっているかわかること。

サンプルコード

sgx_rijndael128GCM_decrypt/encryptをやってみるサンプルです。

Enclave.edl

user_checkが大事なようです。まず最も大事なことは、ポインターで渡そうがなんだろうが、enclave内ではすべて値コピーされます。なので、参照渡しは不可能です。ではどうやって書き換えるかですが、[out]というのを変数の前につけてあげます。[out]をつけると、非Enclave領域に値コピーして書き込んでくれます。このとき、非Enclave側で確保した配列の大きさをsizeで指定してやるのがよさそうです。

public sgx_status_t enclave_enc([in, size = plain_len] unsigned char * plain, 
size_t plain_len, [out, size=cipher_len] unsigned char * cipher, 
size_t cipher_len, [in, out] sgx_aes_gcm_128bit_tag_t * tag);

public sgx_status_t enclave_dec(
  [in, size = cipher_len] unsigned char *cipher, size_t cipher_len,
  [out, size=plain_len] char *plain, size_t plain_len, [in] sgx_aes_gcm_128bit_tag_t *tag);

Enclave.cpp

ポイントはaadにNULLを、ivに12byteの配列を入れること。本サンプルでは定数を用いていますが、ivは必ずランダムに生成してください。

sgx_status_t enclave_enc(unsigned char * plain, size_t plain_len, 
    unsigned char * cipher, size_t cipher_len, sgx_aes_gcm_128bit_tag_t * tag)
{
    sgx_status_t ret;
    sgx_key_128bit_t mk = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    uint8_t iv[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; // 96bit(12byte)?

    ret = sgx_rijndael128GCM_encrypt(&mk, plain, plain_len, cipher, iv, 12, NULL, 0, tag);
    return ret;
}

sgx_status_t enclave_dec(unsigned char * cipher, size_t cipher_len, 
char * plain, size_t plain_len, sgx_aes_gcm_128bit_tag_t * tag)
{
    sgx_key_128bit_t mk = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    sgx_status_t ret;
    uint8_t iv[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; // 96bit(12byte)?

    ret = sgx_rijndael128GCM_decrypt(&mk, cipher, cipher_len, (unsigned char *)plain, iv, 12, NULL, 0, tag);
    return ret;
}

App.cpp

まず暗号化から。ポイントは、App側で領域確保を行うこと。[out, size]設定により、Enclave側でも自動で領域の確保を行ってくれる。暗号化後の文字列のサイズはstrlenで取得できる。

sgx_status_t status, sgxrv;
sgx_aes_gcm_128bit_tag_t tag;
char text[32] = "fizzbuzz";
unsigned char cipher[60] = {};
status = enclave_enc(eid, &sgxrv, (unsigned char*)text, strlen(text), cipher, 60, &tag);
int cipher_len = strlen((char *)cipher);

続いて復号。長さは同様にstrlenで復号できるし、%s使って出力も可能。

char plain[60] = {};
status = enclave_dec(eid, &sgxrv, cipher, cipher_len, plain, 60, &tag);
int plain_len = strlen(plain);
printf("%s\n", plain);
mr68shi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away