LoginSignup
1
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-06-05

本記事の背景

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);
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1