From d6da3e3d9bc29e22103b094bee5ca68f5d8f0f61 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Thu, 21 Jul 2016 16:46:00 +0900 Subject: [PATCH] Add data structures For migrated web app, we need to more fields in cache e.g., IV and is_migrated flag to handle it separately. Because cipher algorithm, iv and key size could be different between old secure storage, it depends on product implementation. So this architecture needs more flexibility. A lot of code changed because of the principle data structure is added from the bottom. Change-Id: Id6a10b9f707f4da25016dd928ab4049be619a610 Signed-off-by: Kyungwook Tak --- srcs/CMakeLists.txt | 2 + srcs/crypto_service.c | 187 ++++++------ srcs/crypto_service.h | 25 +- srcs/decrypt_migrated_wgt.c | 141 +++++---- srcs/decrypt_migrated_wgt.h | 16 +- srcs/key_handler.c | 710 ++++++++++++++++---------------------------- srcs/key_handler.h | 38 +-- srcs/key_manager.c | 393 ++++++++++++++++++++++++ srcs/key_manager.h | 46 +++ srcs/types.c | 255 ++++++++++++++++ srcs/types.h | 65 ++++ srcs/web_app_enc.c | 98 +++--- tests/internals.cpp | 325 ++++++++++---------- tests/non-normals.cpp | 8 +- tests/normals.cpp | 4 +- tests/test-common.cpp | 35 ++- tests/test-common.h | 7 +- tests/test-helper.cpp | 100 +++---- tests/test-helper.h | 4 +- 19 files changed, 1530 insertions(+), 929 deletions(-) create mode 100644 srcs/key_manager.c create mode 100644 srcs/key_manager.h create mode 100644 srcs/types.c create mode 100644 srcs/types.h diff --git a/srcs/CMakeLists.txt b/srcs/CMakeLists.txt index 3de6d18..0b44fdd 100644 --- a/srcs/CMakeLists.txt +++ b/srcs/CMakeLists.txt @@ -25,6 +25,8 @@ SET(WEB_APP_ENC_SOURCES key_handler.c crypto_service.c decrypt_migrated_wgt.c + types.c + key_manager.c ) INCLUDE_DIRECTORIES( diff --git a/srcs/crypto_service.c b/srcs/crypto_service.c index 0991d42..bd83eba 100644 --- a/srcs/crypto_service.c +++ b/srcs/crypto_service.c @@ -36,11 +36,6 @@ #define AES_256_KEY_SIZE 32 -static unsigned char AES_CBC_IV[16] = { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - static bool __initialized = false; void _initialize() @@ -52,26 +47,27 @@ void _initialize() } } -int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, - const unsigned char *dek, size_t dek_len, - unsigned char **pencrypted_dek, size_t *pencrypted_dek_len) +int encrypt_app_dek(const raw_buffer_s *pubkey, const raw_buffer_s *dek, + raw_buffer_s **pencrypted_dek) { + if (!is_buffer_valid(pubkey) || !is_buffer_valid(dek) || pencrypted_dek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + int ret = WAE_ERROR_NONE; EVP_PKEY *key = NULL; - BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; - unsigned char *out = NULL; - size_t out_len = 0; + raw_buffer_s *encrypted_dek = NULL; + size_t len = 0; _initialize(); - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, pubkey, pubkey_len); + BIO *bio = BIO_new(BIO_s_mem()); + BIO_write(bio, pubkey->buf, pubkey->size); key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); if (key == NULL) { BIO_reset(bio); - BIO_write(bio, pubkey, pubkey_len); + BIO_write(bio, pubkey->buf, pubkey->size); key = d2i_PUBKEY_bio(bio, NULL); } @@ -102,28 +98,26 @@ int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, } /* Determine buffer length */ - if (EVP_PKEY_encrypt(ctx, NULL, &out_len, dek, dek_len) <= 0) { + if (EVP_PKEY_encrypt(ctx, NULL, &len, dek->buf, dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(out_len); - - if (out == NULL) { + if ((encrypted_dek = buffer_create(len)) == NULL) { WAE_SLOGE("Encrypt APP DEK Failed. OPENSSL_malloc failed"); ret = WAE_ERROR_MEMORY; goto error; } - if (EVP_PKEY_encrypt(ctx, out, &out_len, dek, dek_len) <= 0) { + if (EVP_PKEY_encrypt(ctx, encrypted_dek->buf, &encrypted_dek->size, dek->buf, + dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_encrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *pencrypted_dek = out; - *pencrypted_dek_len = out_len; + *pencrypted_dek = encrypted_dek; error: if (bio != NULL) @@ -135,39 +129,41 @@ error: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); + if (ret != WAE_ERROR_NONE) + buffer_destroy(encrypted_dek); return ret; } -int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, - const char *prikey_pass, - const unsigned char *encrypted_dek, size_t encrypted_dek_len, - unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len) +int decrypt_app_dek(const raw_buffer_s *prikey, const char *prikey_pass, + const raw_buffer_s *encrypted_dek, raw_buffer_s **pdek) { + if (!is_buffer_valid(prikey) || !is_buffer_valid(encrypted_dek) || pdek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + int ret = WAE_ERROR_NONE; - EVP_PKEY *key = NULL; - BIO *bio = NULL; EVP_PKEY_CTX *ctx = NULL; - unsigned char *out = NULL; - size_t out_len = 0; + raw_buffer_s *dek = NULL; + size_t len = 0; _initialize(); - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, prikey, prikey_len); - key = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)prikey_pass); + BIO *bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + return WAE_ERROR_MEMORY; + + BIO_write(bio, prikey->buf, prikey->size); + EVP_PKEY *key = PEM_read_bio_PrivateKey(bio, NULL, NULL, (void *)prikey_pass); if (key == NULL) { BIO_reset(bio); - BIO_write(bio, prikey, prikey_len); + BIO_write(bio, prikey->buf, prikey->size); key = d2i_PrivateKey_bio(bio, NULL); } if (key == NULL) { ret = WAE_ERROR_FILE; - WAE_SLOGE("Failt to convert to public key."); + WAE_SLOGE("Failed to convert to public key."); goto error; } @@ -192,28 +188,27 @@ int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, } /* Determine buffer length */ - if (EVP_PKEY_decrypt(ctx, NULL, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { + if (EVP_PKEY_decrypt(ctx, NULL, &len, encrypted_dek->buf, encrypted_dek->size) <= 0) { WAE_SLOGE("Decrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - out = OPENSSL_malloc(out_len); - - if (out == NULL) { + dek = buffer_create(len); + if (dek == NULL) { WAE_SLOGE("Decrypt APP DEK Failed. OPENSSL_malloc failed"); ret = WAE_ERROR_MEMORY; goto error; } - if (EVP_PKEY_decrypt(ctx, out, &out_len, encrypted_dek, encrypted_dek_len) <= 0) { + if (EVP_PKEY_decrypt(ctx, dek->buf, &dek->size, encrypted_dek->buf, + encrypted_dek->size) <= 0) { WAE_SLOGE("Encrypt APP DEK Failed. EVP_PKEY_decrypt failed"); ret = WAE_ERROR_CRYPTO; goto error; } - *pdecrypted_dek = out; - *pdecrypted_dek_len = out_len; + *pdek = dek; error: if (bio != NULL) @@ -225,36 +220,40 @@ error: if (ctx != NULL) EVP_PKEY_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && out != NULL) - OPENSSL_free(out); + if (ret != WAE_ERROR_NONE) + buffer_destroy(dek); return ret; } -int encrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len) +int encrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pencrypted_data) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char *ciphertext = NULL; - size_t ciphertext_len; - unsigned char *iv = AES_CBC_IV; + if (!is_crypto_element_valid(ce) || !is_buffer_valid(data) || pencrypted_data == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + EVP_CIPHER_CTX *ctx = NULL; + int len = 0; + raw_buffer_s *encrypted_data = NULL; int ret = WAE_ERROR_NONE; _initialize(); - WAE_SLOGI("Encryption Started. size=%d", data_len); + WAE_SLOGI("Encryption Started. size=%d", data->size); /* check input paramter */ - if (key_len != 32) { - WAE_SLOGE("Encryption Failed. Invalid Key Length. key_len=%d", key_len); + if (ce->dek->size != 32) { + WAE_SLOGE("Encryption Failed. Invalid Key Length. key_len=%d", ce->dek->size); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - ciphertext = (unsigned char *) malloc(data_len + 32); + encrypted_data = buffer_create(data->size + 32); + if (encrypted_data == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -268,7 +267,7 @@ int encrypt_aes_cbc(const unsigned char *key, size_t key_len, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { + if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, ce->dek->buf, ce->iv->buf) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -277,64 +276,68 @@ int encrypt_aes_cbc(const unsigned char *key, size_t key_len, /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ - if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, data, data_len)) { + len = encrypted_data->size; + if (EVP_EncryptUpdate(ctx, encrypted_data->buf, &len, data->buf, + data->size) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; } - ciphertext_len = len; + encrypted_data->size = len; - /* Finalise the encryption. Further ciphertext bytes may be written at + /* Finalise the encryption. Further encrypted data bytes may be written at * this stage. */ - if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { + if (EVP_EncryptFinal_ex(ctx, encrypted_data->buf + encrypted_data->size, &len) != 1) { WAE_SLOGE("Encryption Failed. EVP_EncryptFinal_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; } - ciphertext_len += len; + encrypted_data->size += len; - *pencrypted_data = ciphertext; - *pencrypted_data_len = ciphertext_len; + *pencrypted_data = encrypted_data; - ret = WAE_ERROR_NONE; - WAE_SLOGI("Encryption Ended Successfully. encrypted_len", ciphertext_len); + WAE_SLOGI("Encryption Ended Successfully. encrypted_len: %d", encrypted_data->size); error: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && ciphertext != NULL) - free(ciphertext); + if (ret != WAE_ERROR_NONE) + buffer_destroy(encrypted_data); return ret; } -int decrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) +int decrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *encrypted_data, + raw_buffer_s **pdata) { - EVP_CIPHER_CTX *ctx; - int len; - unsigned char *plaintext = NULL; - size_t plaintext_len; - unsigned char *iv = AES_CBC_IV; + if (!is_crypto_element_valid(ce) || !is_buffer_valid(encrypted_data) || pdata == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + EVP_CIPHER_CTX *ctx = NULL; + int len = 0; + raw_buffer_s *data = NULL; int ret = WAE_ERROR_NONE; _initialize(); - WAE_SLOGI("Decryption Started. size=%d", data_len); + WAE_SLOGI("Decryption Started. size=%d", encrypted_data->size); /* check input paramter */ - if (key_len != 32) { - WAE_SLOGE("Decryption Failed. Invalid Key Length. key_len=%d", key_len); + if (ce->dek->size != 32) { + WAE_SLOGE("Decryption Failed. Invalid Key Length. key_len=%d", ce->dek->size); return WAE_ERROR_INVALID_PARAMETER; } // assing a enough memory for decryption. - plaintext = (unsigned char *) malloc(data_len); + data = buffer_create(encrypted_data->size); + if (data == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } /* Create and initialise the context */ if (!(ctx = EVP_CIPHER_CTX_new())) { @@ -348,7 +351,7 @@ int decrypt_aes_cbc(const unsigned char *key, size_t key_len, * In this example we are using 256 bit AES (i.e. a 256 bit key). The * IV size for *most* modes is the same as the block size. For AES this * is 128 bits */ - if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { + if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, ce->dek->buf, ce->iv->buf) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptInit_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; @@ -357,37 +360,37 @@ int decrypt_aes_cbc(const unsigned char *key, size_t key_len, /* Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ - if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, data, data_len)) { + len = data->size; + if (EVP_DecryptUpdate(ctx, data->buf, &len, encrypted_data->buf, + encrypted_data->size) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptUpdate failed"); ret = WAE_ERROR_CRYPTO; goto error; } - plaintext_len = len; + data->size = len; /* Finalise the decryption. Further plaintext bytes may be written at * this stage. */ - if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { + if (EVP_DecryptFinal_ex(ctx, data->buf + data->size, &len) != 1) { WAE_SLOGE("Decryption Failed. EVP_DecryptFinal_ex failed"); ret = WAE_ERROR_CRYPTO; goto error; } - plaintext_len += len; + data->size += len; - *pdecrypted_data = plaintext; - *pdecrypted_data_len = plaintext_len; + *pdata = data; - ret = WAE_ERROR_NONE; - WAE_SLOGI("Decryption Ended Successfully. decrypted_len", plaintext_len); + WAE_SLOGI("Decryption Ended Successfully. decrypted_len: %d", data->size); error: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); - if (ret != WAE_ERROR_NONE && plaintext != NULL) - free(plaintext); + if (ret != WAE_ERROR_NONE) + buffer_destroy(data); return ret; } diff --git a/srcs/crypto_service.h b/srcs/crypto_service.h index 8a64d6d..c6340ae 100644 --- a/srcs/crypto_service.h +++ b/srcs/crypto_service.h @@ -26,25 +26,18 @@ extern "C" { #endif -#include +#include "types.h" -int encrypt_app_dek(const unsigned char *pubkey, size_t pubkey_len, - const unsigned char *dek, size_t dek_len, - unsigned char **encryptedDek, size_t *encryptedDekLen); +int encrypt_app_dek(const raw_buffer_s *pubkey, const raw_buffer_s *dek, + raw_buffer_s **pencrypted_dek); +int decrypt_app_dek(const raw_buffer_s *prikey, const char *prikey_pass, + const raw_buffer_s *encrypted_dek, raw_buffer_s **pdek); -int decrypt_app_dek(const unsigned char *prikey, size_t prikey_len, - const char *prikey_pass, - const unsigned char *encrypted_dek, size_t encrypted_dek_len, - unsigned char **pdecrypted_dek, size_t *pdecrypted_dek_len); - -int encrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pencrypted_data, size_t *pencrypted_data_len); - -int decrypt_aes_cbc(const unsigned char *key, size_t key_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted_data, size_t *pdecrypted_data_len); +int encrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pencrypted_data); +int decrypt_aes_cbc(const crypto_element_s *ce, const raw_buffer_s *encrypted_data, + raw_buffer_s **pdata); #ifdef __cplusplus } diff --git a/srcs/decrypt_migrated_wgt.c b/srcs/decrypt_migrated_wgt.c index dfaf28a..1012a35 100644 --- a/srcs/decrypt_migrated_wgt.c +++ b/srcs/decrypt_migrated_wgt.c @@ -33,7 +33,7 @@ #include "wae_log.h" #include "web_app_enc.h" -#define DUK_LEN 16 +#define DUK_SIZE 16 static void _logging_openssl_err() { @@ -45,64 +45,62 @@ static void _logging_openssl_err() WAE_SLOGE("Openssl err: %s", buf); } -static int _get_old_duk(const char *pkg_id, unsigned char **pduk, size_t *pduk_len) +static int _get_old_duk(const char *pkg_id, raw_buffer_s **pduk) { + if (pkg_id == NULL || pduk == NULL) + return WAE_ERROR_INVALID_PARAMETER; + unsigned char salt[32]; memset(salt, 0xFF, sizeof(salt)); - unsigned char *duk = (unsigned char *)malloc(sizeof(unsigned char) * ((DUK_LEN * 2) + 1)); - if (duk == NULL) { - WAE_SLOGE("Failed to allocate memory for old duk."); + raw_buffer_s *duk = buffer_create(DUK_SIZE * 2); + if (duk == NULL) return WAE_ERROR_MEMORY; - } if (PKCS5_PBKDF2_HMAC_SHA1(pkg_id, strlen(pkg_id), salt, sizeof(salt), 1, - (DUK_LEN * 2), duk) != 1) { - free(duk); + duk->size, duk->buf) != 1) { + buffer_destroy(duk); return WAE_ERROR_CRYPTO; } - duk[DUK_LEN * 2] = '\0'; + duk->size = DUK_SIZE; *pduk = duk; - *pduk_len = DUK_LEN; - WAE_SLOGD("get old duk of length: %d", *pduk_len); + WAE_SLOGD("get old duk of length: %d", duk->size); return WAE_ERROR_NONE; } -static int _get_old_iv(const unsigned char *src, size_t src_len, unsigned char **piv, size_t *piv_len) +static int _get_old_iv(const raw_buffer_s *src, raw_buffer_s **piv) { - unsigned int iv_len = SHA_DIGEST_LENGTH; - unsigned char *iv = (unsigned char *)malloc(sizeof(unsigned char) * iv_len); + if (!is_buffer_valid(src) || piv == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + raw_buffer_s *iv = buffer_create(SHA_DIGEST_LENGTH); if (iv == NULL) return WAE_ERROR_MEMORY; - if (EVP_Digest(src, src_len, iv, &iv_len, EVP_sha1(), NULL) != 1) { - free(iv); + if (EVP_Digest(src->buf, src->size, iv->buf, &iv->size, EVP_sha1(), NULL) != 1) { + buffer_destroy(iv); return WAE_ERROR_CRYPTO; } *piv = iv; - *piv_len = iv_len; - WAE_SLOGD("get old iv of length: %d", *piv_len); + WAE_SLOGD("get old iv of length: %d", iv->size); return WAE_ERROR_NONE; } -static int _decrypt(const unsigned char *key, size_t key_len, - const unsigned char *iv, size_t iv_len, - const unsigned char *data, size_t data_len, - unsigned char **pdecrypted, size_t *pdecrypted_len) +static int _decrypt(const crypto_element_s *ce, const raw_buffer_s *data, + raw_buffer_s **pdecrypted) { - if (key == NULL || iv == NULL || data == NULL || pdecrypted == NULL || - pdecrypted_len == 0) + if (!is_crypto_element_valid(ce) || !is_buffer_valid(data) || pdecrypted == NULL) return WAE_ERROR_INVALID_PARAMETER; - if (key_len != 16 || iv_len < 16) { + if (ce->dek->size != DUK_SIZE || ce->iv->size < DUK_SIZE) { WAE_SLOGE("Invalid key or iv size for decrypt by aes_128_cbc algorithm. " "key should be 16 bytes and iv should be bigger than 16 bytes"); return WAE_ERROR_INVALID_PARAMETER; @@ -110,22 +108,22 @@ static int _decrypt(const unsigned char *key, size_t key_len, const struct evp_cipher_st *algo = EVP_aes_128_cbc(); - EVP_CIPHER_CTX ctx; - - size_t tmp_len = (data_len / algo->block_size + 1) * algo->block_size; - int decrypted_len = 0; + int in_len = data->size; + int out_len = 0; int final_len = 0; - unsigned char *decrypted = (unsigned char *)calloc(tmp_len, 1); + raw_buffer_s *decrypted = buffer_create( + (in_len / algo->block_size + 1) * algo->block_size); if (decrypted == NULL) return WAE_ERROR_MEMORY; + EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); int ret = WAE_ERROR_NONE; - if (EVP_CipherInit(&ctx, algo, key, iv, 0) != 1) { + if (EVP_CipherInit(&ctx, algo, ce->dek->buf, ce->iv->buf, 0) != 1) { ret = WAE_ERROR_CRYPTO; goto error; } @@ -135,66 +133,85 @@ static int _decrypt(const unsigned char *key, size_t key_len, goto error; } - if (EVP_CipherUpdate(&ctx, decrypted, &decrypted_len, data, data_len) != 1) { + if (EVP_CipherUpdate(&ctx, decrypted->buf, &out_len, data->buf, in_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; - } else if (decrypted_len <= 0) { - WAE_SLOGE("EVP_CipherUpdate success but returned decrypted_len(%d) <= 0", - decrypted_len); - ret = WAE_ERROR_UNKNOWN; - goto error; } - if (EVP_CipherFinal(&ctx, decrypted + decrypted_len, &final_len) != 1) { + if (EVP_CipherFinal(&ctx, decrypted->buf + out_len, &final_len) != 1) { ret = WAE_ERROR_CRYPTO; goto error; - } else if (final_len <= 0) { - WAE_SLOGE("EVP_CipherFinal success but returned final_len(%d) <= 0", - final_len); - ret = WAE_ERROR_UNKNOWN; - goto error; } + decrypted->size = out_len + final_len; + *pdecrypted = decrypted; - *pdecrypted_len = decrypted_len + final_len; error: EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WAE_ERROR_NONE) - free(decrypted); + buffer_destroy(decrypted); return ret; } -int decrypt_by_old_ss_algo(const char *pkg_id, const unsigned char *encrypted, size_t encrypted_len, - unsigned char **pdecrypted, size_t *pdecrypted_len) +int get_old_ss_crypto_element(const char *pkg_id, crypto_element_s **pce) { - unsigned char *duk = NULL; - size_t duk_len = 0; - unsigned char *iv = NULL; - size_t iv_len = 0; + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; - int ret = _get_old_duk(pkg_id, &duk, &duk_len); + raw_buffer_s *duk = NULL; + raw_buffer_s *iv = NULL; + crypto_element_s *ce = NULL; + int ret = _get_old_duk(pkg_id, &duk); if (ret != WAE_ERROR_NONE) - goto error; - - ret = _get_old_iv(duk, duk_len, &iv, &iv_len); + return ret; + ret = _get_old_iv(duk, &iv); if (ret != WAE_ERROR_NONE) goto error; - ret = _decrypt(duk, duk_len, iv, iv_len, encrypted, encrypted_len, pdecrypted, pdecrypted_len); + ce = crypto_element_create(duk, iv); + if (ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } - WAE_SLOGI("decrypt with old ss algo success of pkg: %s", pkg_id); + ce->is_migrated_app = true; + + *pce = ce; + + return WAE_ERROR_NONE; error: - if (ret == WAE_ERROR_CRYPTO) - _logging_openssl_err(); + buffer_destroy(duk); + buffer_destroy(iv); - free(duk); - free(iv); + return ret; +} - return WAE_ERROR_NONE; +int decrypt_by_old_ss_algo(const crypto_element_s *ce, const raw_buffer_s *encrypted, + raw_buffer_s **pdecrypted) +{ + if (!is_crypto_element_valid(ce) || !is_buffer_valid(encrypted) || pdecrypted == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + int ret = _decrypt(ce, encrypted, pdecrypted); + + switch (ret) { + case WAE_ERROR_CRYPTO: + WAE_SLOGE("decrypt with old ss algo failed with crypto error below."); + _logging_openssl_err(); + break; + case WAE_ERROR_NONE: + WAE_SLOGI("decrypt with old ss algo success!"); + break; + default: + WAE_SLOGE("decrypt with old ss algo failed! ret(%d)", ret); + break; + } + + return ret; } diff --git a/srcs/decrypt_migrated_wgt.h b/srcs/decrypt_migrated_wgt.h index 95f481e..42f99ad 100644 --- a/srcs/decrypt_migrated_wgt.h +++ b/srcs/decrypt_migrated_wgt.h @@ -22,10 +22,18 @@ #ifndef __WAE_SS_KEY_GENERATOR_H #define __WAE_SS_KEY_GENERATOR_H -#include +#ifdef __cplusplus +extern "C" { +#endif -int decrypt_by_old_ss_algo(const char *pkg_id, - const unsigned char *encrypted, size_t encrypted_len, - unsigned char **pdecrypted, size_t *pdecrypted_len); +#include "types.h" + +int get_old_ss_crypto_element(const char *pkg_id, crypto_element_s **pce); +int decrypt_by_old_ss_algo(const crypto_element_s *ce, const raw_buffer_s *encrypted, + raw_buffer_s **pdecrypted); + +#ifdef __cplusplus +} +#endif #endif /* __WAE_SS_KEY_GENERATOR_H */ diff --git a/srcs/key_handler.c b/srcs/key_handler.c index 0cb2776..af7280b 100644 --- a/srcs/key_handler.c +++ b/srcs/key_handler.c @@ -27,112 +27,55 @@ #include #include -#include #include #include "wae_log.h" -#include "web_app_enc.h" #include "crypto_service.h" +#include "key_manager.h" +#include "decrypt_migrated_wgt.h" #define RANDOM_FILE "/dev/urandom" #define APP_DEK_KEK_PRIKEY_PASSWORD "wae_appdek_kek_1q2w3e4r" -#define APP_DEK_ALIAS_PFX "APP_DEK_" -#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" #define APP_DEK_FILE_PFX "WAE_APP_DEK" -#define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" #define DEK_LEN 32 -#define MAX_ALIAS_LEN 256 +#define IV_LEN 16 #define MAX_PKGID_LEN 256 #define MAX_CACHE_SIZE 100 -typedef struct _dek_cache_element { - char pkg_id[MAX_PKGID_LEN]; - unsigned char dek[DEK_LEN]; -} dek_cache_element; +static unsigned char AES_CBC_IV[IV_LEN] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x08, 0x39, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; -dek_cache_element APP_DEK_CACHE[MAX_CACHE_SIZE]; -int NEXT_CACHE_IDX = -1; +static crypto_element_map_s *_map; -void _initialize_cache() +static void deinit_lib(void) __attribute__((destructor)); +static void deinit_lib(void) { - NEXT_CACHE_IDX = 0; - memset(APP_DEK_CACHE, 0, sizeof(dek_cache_element) * MAX_CACHE_SIZE); + crypto_element_map_destroy(_map); } -const unsigned char *_get_app_dek_from_cache(const char *pkg_id) +static const crypto_element_s *_get_app_ce_from_cache(const char *pkg_id) { - if (NEXT_CACHE_IDX < 0) - _initialize_cache(); - - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - //WAE_SLOGI("CACHED APP_DEK[%d]=%s", i, APP_DEK_CACHE[i].pkg_id); - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) - return APP_DEK_CACHE[i].dek; - } - - return NULL; + return crypto_element_map_get(_map, pkg_id); } -void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek) +static int _add_app_ce_to_cache(const char *pkg_id, crypto_element_s *ce) { - if (NEXT_CACHE_IDX < 0) - _initialize_cache(); - - // if existing one has the same pkgid - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { - memcpy(APP_DEK_CACHE[i].dek, dek, DEK_LEN); - return; - } - } - - // for new pkgid - strncpy(APP_DEK_CACHE[NEXT_CACHE_IDX].pkg_id, pkg_id, MAX_PKGID_LEN - 1); - memcpy(APP_DEK_CACHE[NEXT_CACHE_IDX].dek, dek, DEK_LEN); - - ++NEXT_CACHE_IDX; - - if (NEXT_CACHE_IDX >= MAX_CACHE_SIZE) - NEXT_CACHE_IDX = 0; + return crypto_element_map_add(&_map, pkg_id, ce); } -void _remove_app_dek_from_cache(const char *pkg_id) +void _remove_app_ce_from_cache(const char *pkg_id) { - for (size_t i = 0; i < MAX_CACHE_SIZE; i++) { - if (strncmp(pkg_id, APP_DEK_CACHE[i].pkg_id, MAX_PKGID_LEN) == 0) { - memset(APP_DEK_CACHE[i].pkg_id, 0, MAX_PKGID_LEN); - return; - } - } - + crypto_element_map_remove(&_map, pkg_id); } -int _to_wae_error(int key_manager_error) +int _get_random(raw_buffer_s *rb) { - switch (key_manager_error) { - case CKMC_ERROR_NONE: - return WAE_ERROR_NONE; - - case CKMC_ERROR_INVALID_PARAMETER: + if (!is_buffer_valid(rb)) return WAE_ERROR_INVALID_PARAMETER; - case CKMC_ERROR_PERMISSION_DENIED: - return WAE_ERROR_PERMISSION_DENIED; - - case CKMC_ERROR_DB_ALIAS_UNKNOWN: - return WAE_ERROR_NO_KEY; - - case CKMC_ERROR_DB_ALIAS_EXISTS: - return WAE_ERROR_KEY_EXISTS; - - default: - return WAE_ERROR_KEY_MANAGER; - } -} - -int _get_random(size_t length, unsigned char *random) -{ FILE *f = fopen(RANDOM_FILE, "r"); if (f == NULL) { @@ -142,100 +85,95 @@ int _get_random(size_t length, unsigned char *random) size_t i = 0; int ch = 0; - while (i < length && (ch = fgetc(f) != EOF)) - random[i++] = (unsigned char)ch; + while (i < rb->size && (ch = fgetc(f) != EOF)) + rb->buf[i++] = (unsigned char)ch; fclose(f); return WAE_ERROR_NONE; } -void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len) +static const char *_get_dek_kek_pub_key_path() { - if (app_type == WAE_DOWNLOADED_NORMAL_APP) { - if (forSave) { - snprintf(alias, buff_len, "%s%s", - APP_DEK_ALIAS_PFX, - pkg_id); - } else { - snprintf(alias, buff_len, "%c%s%s%s%s", - '/', INSTALLER_LABEL, - ckmc_owner_id_separator, - APP_DEK_ALIAS_PFX, - pkg_id); - } - } else { // system alias - snprintf(alias, buff_len, "%s%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_ALIAS_PFX, - pkg_id); - } + return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem"); } -void _get_dek_kek_alias(char *alias, size_t buff_len) +static const char *_get_dek_kek_pri_key_path() { - snprintf(alias, buff_len, "%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_KEK_ALIAS); + return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem"); } -void _get_dek_loading_done_alias(char *alias, size_t buff_len) +static const char *_get_dek_store_path() { - snprintf(alias, buff_len, "%s%s%s", - ckmc_owner_id_system, - ckmc_owner_id_separator, - APP_DEK_LOADING_DONE_ALIAS); + return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); } -const char *_get_dek_kek_pub_key_path() +static int _write_to_file(const char *path, const raw_buffer_s *data) { - return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PublicKey.pem"); -} + if (path == NULL || data == NULL || data->buf == NULL || data->size == 0) + return WAE_ERROR_INVALID_PARAMETER; -const char *_get_dek_kek_pri_key_path() -{ - return tzplatform_mkpath4(TZ_SYS_SHARE, "wae", "app_dek", "WAE_APPDEK_KEK_PrivateKey.pem"); -} + FILE *f = fopen(path, "w"); -const char *_get_dek_store_path() -{ - return tzplatform_mkpath3(TZ_SYS_SHARE, "wae", "app_dek"); + if (f == NULL) { + WAE_SLOGE("WAE: Fail to open a file. file=%s", path); + return WAE_ERROR_FILE; + } + + int write_len = fwrite(data->buf, 1, data->size, f); + + fclose(f); + + if (write_len != (int)data->size) { + WAE_SLOGE("WAE: Fail to write a file. file=%s", path); + return WAE_ERROR_FILE; + } + + return WAE_ERROR_NONE; } -int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len) +static int _read_from_file(const char *path, raw_buffer_s **pdata) { int ret = WAE_ERROR_NONE; - char alias[MAX_ALIAS_LEN] = {0, }; - ckmc_raw_buffer_s buff; - ckmc_policy_s policy; - - buff.data = (unsigned char *)dek; - buff.size = dek_len; + raw_buffer_s *data = NULL; + int ch = 0; + int i = 0; - policy.password = NULL; - policy.extractable = true; + FILE *f = fopen(path, "r"); - _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); + if (f == NULL) { + WAE_SLOGE("Failed to open a file. file=%s", path); + return WAE_ERROR_FILE; + } - // even if it fails to remove, ignore it. - ckmc_remove_alias(alias); + fseek(f, 0, SEEK_END); // move to the end of a file + int file_len = ftell(f); - ret = _to_wae_error(ckmc_save_data(alias, buff, policy)); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to add APP_DEK to key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); - return ret; + if (file_len <= 0) { + WAE_SLOGE("Failed to get file size by ftell. ret: %d", file_len); + ret = WAE_ERROR_FILE; + goto error; } - // share app_dek for web app laucher to use app_dek - ret = _to_wae_error(ckmc_set_permission(alias, pkg_id, CKMC_PERMISSION_READ)); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to set_permission to APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); - return ret; + fseek(f, 0, SEEK_SET); // move to the start of a file + + data = buffer_create(file_len); + if (data == NULL) { + WAE_SLOGE("Failed to allocate memory for encrypted_dek"); + ret = WAE_ERROR_MEMORY; + goto error; } - WAE_SLOGI("WAE: Success to add APP_DEK to key-manager. pkg_id=%s, alias=%s", pkg_id, alias); + while ((ch = fgetc(f)) != EOF) + data->buf[i++] = (char)ch; + + *pdata = data; + +error: + fclose(f); + + if (ret != WAE_ERROR_NONE) + buffer_destroy(data); return ret; } @@ -251,7 +189,7 @@ int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path return WAE_ERROR_NONE; } -int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) +static int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) { char *start = strstr(file_name, APP_DEK_FILE_PFX); @@ -274,238 +212,172 @@ int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id) return WAE_ERROR_NONE; } -int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len) +int _read_encrypted_app_dek_from_file(const char *pkg_id, raw_buffer_s **pencrypted) { char path[MAX_PATH_LEN] = {0,}; _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); - return _read_from_file(path, pencrypted_app_dek, pencrypted_app_dek_len); + return _read_from_file(path, pencrypted); } -int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len) +int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *encrypted) { char path[MAX_PATH_LEN] = {0,}; _get_preloaded_app_dek_file_path(pkg_id, sizeof(path), path); - return _write_to_file(path, encrypted_app_dek, encrypted_app_dek_len); + return _write_to_file(path, encrypted); } -int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len) +int get_app_ce(const char *pkg_id, wae_app_type_e app_type, bool create_for_migrated_app, + const crypto_element_s **pce) { - int ret = WAE_ERROR_NONE; - unsigned char *file_contents = NULL; - int ch = 0; - int i = 0; - - FILE *f = fopen(path, "r"); + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; - if (f == NULL) { - WAE_SLOGE("WAE: Fail to open a file. file=%s", path); - return WAE_ERROR_FILE; + const crypto_element_s *cached_ce = _get_app_ce_from_cache(pkg_id); + if (cached_ce != NULL) { + WAE_SLOGD("cache hit of app ce for pkg_id(%s)", pkg_id); + *pce = cached_ce; + return WAE_ERROR_NONE; } - fseek(f, 0, SEEK_END); // move to the end of a file - int file_len = ftell(f); + WAE_SLOGD("cache miss of app ce for pkg_id(%s)", pkg_id); - if (file_len <= 0) { - WAE_SLOGE("WAE: Failed to get file size by ftell. ret: %d", file_len); - ret = WAE_ERROR_FILE; - goto error; - } + crypto_element_s *ce = NULL; + int ret = get_from_key_manager(pkg_id, app_type, &ce); - fseek(f, 0, SEEK_SET); // move to the start of a file + if (create_for_migrated_app && + (ret == WAE_ERROR_NO_KEY && app_type == WAE_DOWNLOADED_GLOBAL_APP)) { + WAE_SLOGI("No dek found for pkg_id(%s)! It should be migrated app.", pkg_id); - file_contents = (unsigned char *)malloc(file_len); + if ((ret = get_old_ss_crypto_element(pkg_id, &ce)) != WAE_ERROR_NONE) + goto error; - if (file_contents == NULL) { - WAE_SLOGE("WAE: Fail to allocate memory for encrypted_app_dek"); - ret = WAE_ERROR_MEMORY; + // (k.tak) disable to save ce to key-maanger for migrated app because of permission issue. + //ret = save_to_key_manager(pkg_id, app_type, ce); + //if (ret != WAE_ERROR_NONE) { + // WAE_SLOGW("Failed to save migrated app ce to key-manager with ret(%d). " + // "Ignore this error because we can create ce later again.", ret); + // ret = WAE_ERROR_NONE; + //} + } else if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to get crypto element from key-manager. pkg_id=%s, ret=%d", + pkg_id, ret); goto error; } - memset(file_contents, 0x00, file_len); + ret = _add_app_ce_to_cache(pkg_id, ce); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); + goto error; + } - while ((ch = fgetc(f)) != EOF) - file_contents[i++] = (char)ch; + *pce = ce; - *pdata = file_contents; - *pdata_len = file_len; + WAE_SLOGD("Successfully get ce! pkgid(%s)", pkg_id); -error: - fclose(f); + return WAE_ERROR_NONE; - if (ret != WAE_ERROR_NONE) - free(file_contents); +error: + crypto_element_destroy(ce); return ret; } -int _write_to_file(const char *path, const unsigned char *data, size_t data_len) +int create_app_ce(const char *pkg_id, wae_app_type_e app_type, const crypto_element_s **pce) { - FILE *f = fopen(path, "w"); + raw_buffer_s *dek = buffer_create(DEK_LEN); + raw_buffer_s *iv = buffer_create(IV_LEN); + crypto_element_s *ce = crypto_element_create(dek, iv); - if (f == NULL) { - WAE_SLOGE("WAE: Fail to open a file. file=%s", path); - return WAE_ERROR_FILE; - } - - int write_len = fwrite(data, 1, data_len, f); - - fclose(f); - - if (write_len != (int)data_len) { - WAE_SLOGE("WAE: Fail to write a file. file=%s", path); - return WAE_ERROR_FILE; - } - - return WAE_ERROR_NONE; -} - -int get_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) -{ int ret = WAE_ERROR_NONE; - ckmc_raw_buffer_s *dek_buffer = NULL; - char alias[MAX_ALIAS_LEN] = {0, }; - - const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); - - if (cached_dek == NULL) { - // get APP_DEK from system database - _get_alias(pkg_id, app_type, false, alias, sizeof(alias)); - - ret = _to_wae_error(ckmc_get_data(alias, NULL, &dek_buffer)); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Failed to get APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", - pkg_id, alias, ret); - goto error; - } else if (dek_buffer == NULL || dek_buffer->data == NULL) { - WAE_SLOGE("key-manager success but buffer is null for getting dek of pkg_id=%s", - pkg_id); - ret = WAE_ERROR_KEY_MANAGER; - goto error; - } else if (dek_buffer->size != DEK_LEN) { - WAE_SLOGE("DEK's length which has been saved in key-manager is not valid!"); - ret = WAE_ERROR_KEY_MANAGER; - goto error; - } - - WAE_SLOGD("Successfully get dek from key-manager for pkgid=%s", pkg_id); - cached_dek = dek_buffer->data; - } - - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); + if (ce == NULL) { ret = WAE_ERROR_MEMORY; goto error; } - memcpy(dek, cached_dek, DEK_LEN); - - *pdek = dek; - *pdek_len = DEK_LEN; - - WAE_SLOGI("WAE: Success to get APP_DEK from key-manager. pkg_id=%s, alias=%s", - pkg_id, alias); - -error: - ckmc_buffer_free(dek_buffer); - - if (ret != WAE_ERROR_NONE) - free(dek); - - return ret; -} - -int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len) -{ - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) - return WAE_ERROR_MEMORY; - - int ret = _get_random(DEK_LEN, dek); + memcpy(ce->iv->buf, AES_CBC_IV, ce->iv->size); + ret = _get_random(dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to get random for APP_DEK. pkg_id=%s, ret=%d", pkg_id, ret); + WAE_SLOGE("Failed to get random for dek. pkg_id(%s) ret(%d)", pkg_id, ret); goto error; } - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkg_id, app_type, dek, DEK_LEN); - + ret = save_to_key_manager(pkg_id, app_type, ce); if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to save ce to key-manager. pkg_id(%s) app_type(%d) ret(%d)", + pkg_id, app_type, ret); goto error; } - // store APP_DEK in cache - _add_app_dek_to_cache(pkg_id, dek); + ret = _add_app_ce_to_cache(pkg_id, ce); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); + goto error; + } - *pdek = dek; - *pdek_len = DEK_LEN; + *pce = ce; - WAE_SLOGI("WAE: Success to create APP_DEK and store it in key-manager. pkg_id=%s", pkg_id); + WAE_SLOGI("Success to create dek/iv and store it in key-manager. pkg_id(%s)", pkg_id); return WAE_ERROR_NONE; error: - free(dek); + if (ce == NULL) { + buffer_destroy(dek); + buffer_destroy(iv); + } else { + crypto_element_destroy(ce); + } return ret; } -int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) +int get_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce) { - const unsigned char *cached_dek = _get_app_dek_from_cache(pkg_id); + const crypto_element_s *cached_ce = _get_app_ce_from_cache(pkg_id); - if (cached_dek == NULL) { + if (cached_ce == NULL) { WAE_SLOGE("WAE: Fail to get APP_DEK from cache for preloaded app"); return WAE_ERROR_NO_KEY; } - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); - - if (dek == NULL) { - WAE_SLOGE("WAE: Fail to allocate memory for preloaded app dek"); - return WAE_ERROR_MEMORY; - } - - memcpy(dek, cached_dek, DEK_LEN); - - *pdek = dek; - *pdek_len = DEK_LEN; + *pce = cached_ce; return WAE_ERROR_NONE; } -int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len) +int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce) { - unsigned char *encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char *pubkey = NULL; - size_t pubkey_len = 0; + raw_buffer_s *encrypted_app_dek = NULL; + raw_buffer_s *pubkey = NULL; + raw_buffer_s *dek = buffer_create(DEK_LEN); + raw_buffer_s *iv = buffer_create(sizeof(AES_CBC_IV)); + crypto_element_s *ce = crypto_element_create(dek, iv); - // create APP_DEK - unsigned char *dek = (unsigned char *)malloc(DEK_LEN); + int ret = WAE_ERROR_NONE; - if (dek == NULL) - return WAE_ERROR_MEMORY; + if (dek == NULL || iv == NULL || ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } - int ret = _get_random(DEK_LEN, dek); + ret = _get_random(dek); if (ret != WAE_ERROR_NONE) goto error; - // encrypt APP_DEK with APP_DEK_KEK - ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubkey, &pubkey_len); + // copy default iv for preloaded app + memcpy(iv->buf, AES_CBC_IV, sizeof(AES_CBC_IV)); + + ret = _read_from_file(_get_dek_kek_pub_key_path(), &pubkey); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Public Key"); goto error; } - ret = encrypt_app_dek(pubkey, pubkey_len, dek, DEK_LEN, &encrypted_app_dek, &encrypted_app_dek_len); + ret = encrypt_app_dek(pubkey, dek, &encrypted_app_dek); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("WAE: Fail to encrypt APP_DEK with APP_DEK_KEK"); @@ -513,139 +385,48 @@ int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *p } // write APP_DEK in a file - ret = _write_encrypted_app_dek_to_file(pkg_id, encrypted_app_dek, encrypted_app_dek_len); + ret = _write_encrypted_app_dek_to_file(pkg_id, encrypted_app_dek); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to write encrypted APP_DEK. pkg_id=%s", pkg_id); + WAE_SLOGE("Failed to write encrypted dek to file. pkg_id(%s)", pkg_id); goto error; } // store APP_DEK in cache - _add_app_dek_to_cache(pkg_id, dek); - - *pdek = dek; - *pdek_len = DEK_LEN; - WAE_SLOGI("WAE: Success to create preleaded APP_DEK and write it in initail value file. pkg_id=%s", pkg_id); - -error: - free(pubkey); - free(encrypted_app_dek); - - if (ret != WAE_ERROR_NONE) - free(dek); - - return ret; -} - -int _get_app_dek_kek(unsigned char **pdek_kek, size_t *pdek_kek_len) -{ - int ret = _read_from_file(_get_dek_kek_pri_key_path(), pdek_kek, pdek_kek_len); - - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("WAE: Fail to read APP_DEK_KEK Private Key"); - return ret; - } - -#if 0 - ckmc_raw_buffer_s *kek_buffer = NULL; - unsigned char* kek = NULL; - - char dek_kek_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_kek_alias(dek_kek_alias, sizeof(dek_kek_alias)); - - ret = _to_wae_error(ckmc_get_data(dek_kek_alias, NULL, &kek_buffer)); + _add_app_ce_to_cache(pkg_id, ce); if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to get APP_DEK_KEK from key-manager. alias=%s, ret=%d", - APP_DEK_KEK_ALIAS, ret); - goto error; + WAE_SLOGE("Failed to add ce to cache for pkg_id(%s) ret(%d)", pkg_id, ret); + goto error; } - kek = (unsigned char *)malloc(kek_buffer->size); - if(kek == NULL) { - WAE_SLOGE("Fail to allocate a memory"); - ret = WAE_ERROR_MEMORY; - goto error; - } - memcpy(kek, kek_buffer->data, kek_buffer->size); + *pce = ce; - *pdek_kek = kek; - *pdek_kek_len = kek_buffer->size; - WAE_SLOGI("Success to get APP_DEK_KEK from key-manager."); + WAE_SLOGI("Success to create preleaded dek and write it in initial value file. " + "pkg_id(%s)", pkg_id); error: - ckmc_buffer_free(kek_buffer); - free(kek); -#endif - - return ret; -} - -int _get_app_deks_loaded() -{ - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - ckmc_raw_buffer_s *buffer = NULL; - int ret = _to_wae_error(ckmc_get_data(loading_done_alias, NULL, &buffer)); - - if (ret == WAE_ERROR_NO_KEY) - WAE_SLOGI("WAE: APP_DEK_LOADING was not done"); - else if (ret == WAE_ERROR_NONE) - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - else - WAE_SLOGE("WAE: Fail to get information from key-manager about APP_DEK_LOADING_DONE_ALIAS. ret=%d", ret); - - ckmc_buffer_free(buffer); + buffer_destroy(encrypted_app_dek); + buffer_destroy(pubkey); - return ret; -} - -int _set_app_deks_loaded() -{ - ckmc_raw_buffer_s buff; - ckmc_policy_s policy; - unsigned char dummy_data[1] = {0}; - - buff.data = dummy_data; - buff.size = sizeof(dummy_data); - - policy.password = NULL; - policy.extractable = true; - - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - int ret = _to_wae_error(ckmc_save_data(loading_done_alias, buff, policy)); - - if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("WAE: APP_DEK_LOADING was already done"); - ret = WAE_ERROR_NONE; - } else if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to set APP_DEK_LOADING_DONE_ALIAS to key-manager."); - } else { - WAE_SLOGE("WAE: Fail to set APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); + if (ret != WAE_ERROR_NONE) { + if (ce) { + crypto_element_destroy(ce); + } else { + buffer_destroy(dek); + buffer_destroy(iv); + } } return ret; } -int _clear_app_deks_loaded() +int _get_app_dek_kek(raw_buffer_s **pdek_kek) { - char loading_done_alias[MAX_ALIAS_LEN] = {0, }; - _get_dek_loading_done_alias(loading_done_alias, sizeof(loading_done_alias)); - - int ret = _to_wae_error(ckmc_remove_alias(loading_done_alias)); - - if (ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("APP_DEK_LOADING_DONE_ALIAS was not set to key-manager before."); - ret = WAE_ERROR_NONE; - } else if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to clear app deks loaded"); - } else { - WAE_SLOGE("Fail to clear APP_DEK_LOADING_DONE_ALIAS to key-manager. ret=%d", ret); - } - - return ret; +#if 0 + return get_dek_kek_from_key_manager(pdek_kek); +#else + return _read_from_file(_get_dek_kek_pri_key_path(), pdek_kek); +#endif } int load_preloaded_app_deks(bool reload) @@ -655,24 +436,23 @@ int load_preloaded_app_deks(bool reload) char pkg_id[MAX_PKGID_LEN] = {0, }; char file_path_buff[MAX_PATH_LEN]; - unsigned char *encrypted_app_dek = NULL; - size_t encrypted_app_dek_len = 0; - unsigned char *app_dek = NULL; - size_t app_dek_len = 0; - unsigned char *prikey = NULL; - size_t prikey_len = 0; + raw_buffer_s *encrypted_dek = NULL; + raw_buffer_s *dek = NULL; + raw_buffer_s *iv = NULL; + raw_buffer_s *prikey = NULL; + crypto_element_s *ce = NULL; int error_during_loading = 0; if (!reload) { // check if all deks were already loaded into key-manager. - ret = _get_app_deks_loaded(); + ret = is_app_deks_loaded_in_key_manager(); if (ret == WAE_ERROR_NONE) return ret; } - ret = _get_app_dek_kek(&prikey, &prikey_len); + ret = _get_app_dek_kek(&prikey); if (ret != WAE_ERROR_NONE) { WAE_SLOGE("Fail to get APP_DEK_KEK Private Key"); @@ -706,7 +486,6 @@ int load_preloaded_app_deks(bool reload) if (entry.d_type != DT_REG || strstr(entry.d_name, APP_DEK_FILE_PFX) == NULL) continue; - memset(file_path_buff, 0, sizeof(file_path_buff)); ret = snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", _get_dek_store_path(), entry.d_name); @@ -719,75 +498,92 @@ int load_preloaded_app_deks(bool reload) ret = _extract_pkg_id_from_file_name(entry.d_name, pkg_id); if (ret != WAE_ERROR_NONE) { - WAE_SLOGW("Fail to extract pkgid from file. It will be ignored. file=%s", file_path_buff); + WAE_SLOGW("Failed to extract pkgid from file. It will be ignored. file=%s", + file_path_buff); continue; } - ret = _read_from_file(file_path_buff, &encrypted_app_dek, &encrypted_app_dek_len); + ret = _read_from_file(file_path_buff, &encrypted_dek); - if (ret != WAE_ERROR_NONE || encrypted_app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to read file. It will be ignored. file=%s", file_path_buff); + if (ret != WAE_ERROR_NONE || encrypted_dek == NULL) { + ++error_during_loading; + WAE_SLOGW("Failed to read file. It will be ignored. file=%s", file_path_buff); continue; } - ret = decrypt_app_dek(prikey, prikey_len, APP_DEK_KEK_PRIKEY_PASSWORD, - encrypted_app_dek, encrypted_app_dek_len, - &app_dek, &app_dek_len); + ret = decrypt_app_dek(prikey, APP_DEK_KEK_PRIKEY_PASSWORD, encrypted_dek, &dek); - if (ret != WAE_ERROR_NONE || app_dek == NULL) { - error_during_loading++; - WAE_SLOGW("Fail to decrypt APP DEK. It will be ignored. file=%s", file_path_buff); + buffer_destroy(encrypted_dek); + encrypted_dek = NULL; + + if (ret != WAE_ERROR_NONE || dek == NULL) { + ++error_during_loading; + WAE_SLOGW("Failed to decrypt dek. It will be ignored. file=%s", + file_path_buff); continue; } + iv = buffer_create(IV_LEN); + if (iv == NULL) { + ++error_during_loading; + buffer_destroy(dek); + dek = NULL; + continue; + } + + memcpy(iv->buf, AES_CBC_IV, iv->size); - // save app_dek in key_manager - ret = _add_dek_to_key_manager(pkg_id, WAE_PRELOADED_APP, app_dek, app_dek_len); - // free temp objects - free(app_dek); - free(encrypted_app_dek); - app_dek = NULL; - encrypted_app_dek = NULL; + ce = crypto_element_create(dek, iv); + if (ce == NULL) { + ++error_during_loading; + buffer_destroy(iv); + iv = NULL; + buffer_destroy(dek); + dek = NULL; + continue; + } + + ret = save_to_key_manager(pkg_id, WAE_PRELOADED_APP, ce); if (ret == WAE_ERROR_KEY_EXISTS) { - WAE_SLOGI("Key Manager already has APP_DEK. It will be ignored. file=%s", file_path_buff); + WAE_SLOGI("Key Manager already has dek. It will be ignored. file=%s", + file_path_buff); } else if (ret != WAE_ERROR_NONE) { - error_during_loading++; + ++error_during_loading; WAE_SLOGW("Fail to add APP DEK to key-manager. file=%s", file_path_buff); } + + crypto_element_destroy(ce); + ce = NULL; } - ret = _set_app_deks_loaded(); + ret = set_app_deks_loaded_to_key_manager(); - if (ret == WAE_ERROR_NONE) { - WAE_SLOGI("Success to load_preloaded_app_deks"); - ret = WAE_ERROR_NONE; - } else { - WAE_SLOGW("Fail to _set_app_deks_loaded to key-manager. ret=%d", ret); +error: + if (ret != WAE_ERROR_NONE) { + if (ce) { + crypto_element_destroy(ce); + } else { + buffer_destroy(dek); + buffer_destroy(iv); + } } -error: - free(prikey); + buffer_destroy(prikey); closedir(dir); return ret; } -int remove_app_dek(const char *pkg_id, wae_app_type_e app_type) +int remove_app_ce(const char *pkg_id, wae_app_type_e app_type) { - char alias[MAX_ALIAS_LEN] = {0,}; - - _get_alias(pkg_id, app_type, true, alias, sizeof(alias)); - - int ret = _to_wae_error(ckmc_remove_alias(alias)); + int ret = remove_from_key_manager(pkg_id, app_type); - if (ret != WAE_ERROR_NONE) { - WAE_SLOGE("Fail to remove APP_DEK from key-manager. pkg_id=%s, alias=%s, ret=%d", pkg_id, alias, ret); - return ret; - } + if (ret != WAE_ERROR_NONE) + WAE_SLOGE("Failed to remove app ce for pkg_id(%s) ret(%d)", pkg_id, ret); + else + WAE_SLOGI("Success to remove app ce for pkg_id(%s)", pkg_id); - _remove_app_dek_from_cache(pkg_id); - WAE_SLOGI("Success to remove APP_DEK from key-manager. pkg_id=%s", pkg_id); + _remove_app_ce_from_cache(pkg_id); - return WAE_ERROR_NONE; + return ret; } diff --git a/srcs/key_handler.h b/srcs/key_handler.h index c2e65a7..e64d81c 100644 --- a/srcs/key_handler.h +++ b/srcs/key_handler.h @@ -28,40 +28,28 @@ extern "C" { #include #include + #include "web_app_enc.h" +#include "types.h" #define MAX_PATH_LEN 512 /* functions with "_" prefix are internal static functions but declared here for testing */ -void _initialize_cache(); -const unsigned char *_get_app_dek_from_cache(const char *pkg_id); -void _add_app_dek_to_cache(const char *pkg_id, const unsigned char *dek); -void _remove_app_dek_from_cache(const char *pkg_id); -int _get_random(size_t length, unsigned char *random); -void _get_alias(const char *pkg_id, wae_app_type_e app_type, bool forSave, char *alias, size_t buff_len); -void _get_dek_kek_alias(char *alias, size_t buff_len); -void _get_dek_loading_done_alias(char *alias, size_t buff_len); -const char *_get_dek_kek_pub_key_path(); -const char *_get_dek_kek_pri_key_path(); -const char *_get_dek_store_path(); -int _add_dek_to_key_manager(const char *pkg_id, wae_app_type_e app_type, const unsigned char *dek, size_t dek_len); +void _remove_app_ce_from_cache(const char *pkg_id); +int _get_random(raw_buffer_s *rb); int _get_preloaded_app_dek_file_path(const char *pkg_id, size_t size, char *path); -int _extract_pkg_id_from_file_name(const char *file_name, char *pkg_id); -int _read_encrypted_app_dek_from_file(const char *pkg_id, unsigned char **pencrypted_app_dek, size_t *pencrypted_app_dek_len); -int _write_encrypted_app_dek_to_file(const char *pkg_id, const unsigned char *encrypted_app_dek, size_t encrypted_app_dek_len); -int _read_from_file(const char *path, unsigned char **pdata, size_t *pdata_len); -int _write_to_file(const char *path, const unsigned char *data, size_t data_len); -int _get_app_deks_loaded(); -int _set_app_deks_loaded(); -int _clear_app_deks_loaded(); +int _read_encrypted_app_dek_from_file(const char *pkg_id, raw_buffer_s **pencrypted); +int _write_encrypted_app_dek_to_file(const char *pkg_id, const raw_buffer_s *encrypted); /* functions for interface */ -int get_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); -int create_app_dek(const char *pkg_id, wae_app_type_e app_type, unsigned char **pdek, size_t *pdek_len); -int get_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); -int create_preloaded_app_dek(const char *pkg_id, unsigned char **pdek, size_t *pdek_len); +int get_app_ce(const char *pkg_id, wae_app_type_e app_type, bool create_for_migrated_app, + const crypto_element_s **pce); +int create_app_ce(const char *pkg_id, wae_app_type_e app_type, + const crypto_element_s **pce); +int get_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); +int create_preloaded_app_ce(const char *pkg_id, const crypto_element_s **pce); int load_preloaded_app_deks(bool reload); -int remove_app_dek(const char *pkg_id, wae_app_type_e app_type); +int remove_app_ce(const char *pkg_id, wae_app_type_e app_type); #ifdef __cplusplus } diff --git a/srcs/key_manager.c b/srcs/key_manager.c new file mode 100644 index 0000000..4ef5b8a --- /dev/null +++ b/srcs/key_manager.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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 + * + * + * @file key_manager.c + * @author Kyungwook Tak + * @version 1.0 + * @brief Serialize/deserialize crypto element and save/get to key-manager + */ +#include "key_manager.h" + +#include +#include +#include + +#include + +#include "wae_log.h" + +#define MAX_ALIAS_LEN 256 +#define APP_DEK_ALIAS_PFX "APP_DEK_" +#define APP_DEK_LOADING_DONE_ALIAS "APP_DEKS_LOADING_FINISHED" +#define APP_DEK_KEK_ALIAS "WAE_APP_DEK_KEK" + +static int _to_wae_error(int key_manager_error) +{ + switch (key_manager_error) { + case CKMC_ERROR_NONE: + return WAE_ERROR_NONE; + + case CKMC_ERROR_INVALID_PARAMETER: + return WAE_ERROR_INVALID_PARAMETER; + + case CKMC_ERROR_PERMISSION_DENIED: + return WAE_ERROR_PERMISSION_DENIED; + + case CKMC_ERROR_DB_ALIAS_UNKNOWN: + return WAE_ERROR_NO_KEY; + + case CKMC_ERROR_DB_ALIAS_EXISTS: + return WAE_ERROR_KEY_EXISTS; + + case CKMC_ERROR_OUT_OF_MEMORY: + return WAE_ERROR_MEMORY; + + default: + return WAE_ERROR_KEY_MANAGER; + } +} + +static int _serialize(const crypto_element_s *ce, ckmc_raw_buffer_s **pbuf) +{ + if (!is_crypto_element_valid(ce) || pbuf == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + size_t total_len = sizeof(size_t) * 3 + ce->dek->size + ce->iv->size + sizeof(bool); + + WAE_SLOGD("(serialization) total(%d) dek(%d) iv(%d) is_migrated(%d)", + total_len, ce->dek->size, ce->iv->size, ce->is_migrated_app); + + unsigned char *_buf = (unsigned char *)malloc(total_len); + if (_buf == NULL) + return WAE_ERROR_MEMORY; + + ckmc_raw_buffer_s *buf = NULL; + int ret = _to_wae_error(ckmc_buffer_new(_buf, total_len, &buf)); + + free(_buf); + + if (ret != WAE_ERROR_NONE) + return ret; + + size_t pos = 0; + memcpy(buf->data, &total_len, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, &ce->dek->size, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, ce->dek->buf, ce->dek->size); + pos += ce->dek->size; + memcpy(buf->data + pos, &ce->iv->size, sizeof(size_t)); + pos += sizeof(size_t); + memcpy(buf->data + pos, ce->iv->buf, ce->iv->size); + pos += ce->iv->size; + memcpy(buf->data + pos, &ce->is_migrated_app, sizeof(bool)); + pos += sizeof(bool); + + if (total_len != pos) { + WAE_SLOGE("(serialization) total len(%d) and actualy written byte(%d) " + "isn't matched!", total_len, pos); + ckmc_buffer_free(buf); + return WAE_ERROR_UNKNOWN; + } + + *pbuf = buf; + + WAE_SLOGD("(serialization) success!"); + + return WAE_ERROR_NONE; +} + +static int _deserialize(const ckmc_raw_buffer_s *buf, crypto_element_s **pce) +{ + if (buf == NULL || buf->data == NULL || buf->size == 0 || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + size_t dek_size = 0; + size_t iv_size = 0; + bool is_migrated_app = false; + size_t pos = 0; + size_t total_len = 0; + crypto_element_s *ce = NULL; + + memcpy(&total_len, buf->data, sizeof(size_t)); + pos += sizeof(size_t); + + if (buf->size != total_len) { + WAE_SLOGE("(deserialization) total len(%d) and actualy written byte(%d) " + "isn't matched!", total_len, buf->size); + return WAE_ERROR_UNKNOWN; + } + + // deserialize dek size + memcpy(&dek_size, buf->data + pos, sizeof(size_t)); + pos += sizeof(size_t); + + raw_buffer_s *dek = buffer_create(dek_size); + if (dek == NULL) + return WAE_ERROR_MEMORY; + + // deserialize dek + memcpy(dek->buf, buf->data + pos, dek->size); + pos += dek->size; + + // deserialize iv size + memcpy(&iv_size, buf->data + pos, sizeof(size_t)); + pos += sizeof(size_t); + + raw_buffer_s *iv = buffer_create(iv_size); + int ret = WAE_ERROR_NONE; + if (iv == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + + // deserialize iv + memcpy(iv->buf, buf->data + pos, iv->size); + pos += iv->size; + + // deserialize is_migrated_app + memcpy(&is_migrated_app, buf->data + pos, sizeof(bool)); + pos += sizeof(bool); + + WAE_SLOGD("(deserialization) total(%d) dek(%d) iv(%d) is_migrated(%d)", + total_len, dek_size, iv_size, is_migrated_app); + + if (pos != buf->size) { + WAE_SLOGE("(deserialization) raw buffer remained after deserializatation done!"); + ret = WAE_ERROR_UNKNOWN; + goto error; + } + + ce = crypto_element_create(dek, iv); + if (ce == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + + ce->is_migrated_app = is_migrated_app; + + *pce = ce; + + WAE_SLOGD("(deserialization) success!"); + + return WAE_ERROR_NONE; + +error: + buffer_destroy(dek); + buffer_destroy(iv); + + return ret; +} + +static void _get_alias(const char *pkg_id, wae_app_type_e type, bool forSave, + char *alias, size_t buff_len) +{ + if (type == WAE_DOWNLOADED_NORMAL_APP) { + if (forSave) { + snprintf(alias, buff_len, "%s%s", + APP_DEK_ALIAS_PFX, + pkg_id); + } else { + snprintf(alias, buff_len, "%c%s%s%s%s", + '/', INSTALLER_LABEL, + ckmc_owner_id_separator, + APP_DEK_ALIAS_PFX, + pkg_id); + } + } else { // system alias + snprintf(alias, buff_len, "%s%s%s%s", + ckmc_owner_id_system, + ckmc_owner_id_separator, + APP_DEK_ALIAS_PFX, + pkg_id); + } +} + +static void _get_dek_loading_done_alias(char *alias, size_t buff_len) +{ + snprintf(alias, buff_len, "%s%s%s", + ckmc_owner_id_system, + ckmc_owner_id_separator, + APP_DEK_LOADING_DONE_ALIAS); +} + +bool is_app_deks_loaded_in_key_manager() +{ + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_dek_loading_done_alias(alias, sizeof(alias)); + + ckmc_raw_buffer_s *buf = NULL; + int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); + + ckmc_buffer_free(buf); + + switch (ret) { + case WAE_ERROR_NONE: + return true; + case WAE_ERROR_NO_KEY: + WAE_SLOGI("app dek loading isn't done yet"); + return false; + default: + WAE_SLOGE("Failed to get dek loading flag data from key-manager. ret(%d)", ret); + return false; + } +} + +int set_app_deks_loaded_to_key_manager() +{ + unsigned char dummy_data[1] = {0}; + ckmc_raw_buffer_s buf; + buf.data = dummy_data; + buf.size = sizeof(dummy_data); + + ckmc_policy_s policy; + policy.password = NULL; + policy.extractable = true; + + char alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_loading_done_alias(alias, sizeof(alias)); + + int ret = _to_wae_error(ckmc_save_data(alias, buf, policy)); + if (ret == WAE_ERROR_KEY_EXISTS) + ret = WAE_ERROR_NONE; + + return ret; +} + +int clear_app_deks_loaded_from_key_manager() +{ + char alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_loading_done_alias(alias, sizeof(alias)); + + return _to_wae_error(ckmc_remove_alias(alias)); +} + +int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_element_s *ce) +{ + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_alias(pkg_id, type, true, alias, sizeof(alias)); + + ckmc_raw_buffer_s *buf = NULL; + int ret = _serialize(ce, &buf); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to serialize crypto element of pkg_id: %s", pkg_id); + return ret; + } + + ckmc_policy_s policy; + policy.password = NULL; + policy.extractable = true; + + ret = _to_wae_error(ckmc_save_data(alias, *buf, policy)); + + ckmc_buffer_free(buf); + + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to add crypto element to ckm: pkg_id(%s) alias(%s) ret(%d)", + pkg_id, alias, ret); + return ret; + } + + ret = _to_wae_error(ckmc_set_permission(alias, pkg_id, CKMC_PERMISSION_READ)); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to set perm of crypto element: pkg_id(%s) alias(%s) ret(%d)", + pkg_id, alias, ret); + + ckmc_remove_alias(alias); // rollback + return ret; + } + + WAE_SLOGI("Success to save crypto element to key-manager. pkg_id(%s)", pkg_id); + + return WAE_ERROR_NONE; +} + +int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element_s **pce) +{ + if (pkg_id == NULL || pce == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_alias(pkg_id, type, false, alias, sizeof(alias)); + + ckmc_raw_buffer_s *buf = NULL; + int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); + if (ret != WAE_ERROR_NONE) + return ret; + + ret = _deserialize(buf, pce); + + ckmc_buffer_free(buf); + + return ret; +} + +int remove_from_key_manager(const char *pkg_id, wae_app_type_e type) +{ + char alias[MAX_ALIAS_LEN] = {0, }; + + _get_alias(pkg_id, type, true, alias, sizeof(alias)); + + return _to_wae_error(ckmc_remove_alias(alias)); +} + +static void _get_dek_kek_alias(char *alias, size_t buff_len) +{ + snprintf(alias, buff_len, "%s%s%s", + ckmc_owner_id_system, + ckmc_owner_id_separator, + APP_DEK_KEK_ALIAS); +} + +int get_dek_kek_from_key_manager(raw_buffer_s **pdek_kek) +{ + if (pdek_kek == NULL) + return WAE_ERROR_INVALID_PARAMETER; + + ckmc_raw_buffer_s *buf = NULL; + + char alias[MAX_ALIAS_LEN] = {0, }; + _get_dek_kek_alias(alias, sizeof(alias)); + + int ret = _to_wae_error(ckmc_get_data(alias, NULL, &buf)); + if (ret != WAE_ERROR_NONE) { + WAE_SLOGE("Failed to get dek kek from key-manager. alias(%s) ret(%d)", + alias, ret); + return ret; + } + + raw_buffer_s *dek_kek = buffer_create(buf->size); + if (dek_kek == NULL) { + ret = WAE_ERROR_MEMORY; + goto error; + } + memcpy(dek_kek->buf, buf->data, dek_kek->size); + + *pdek_kek = dek_kek; + + WAE_SLOGI("Success to get dek kek from key-manager."); + +error: + ckmc_buffer_free(buf); + + if (ret != WAE_ERROR_NONE) + buffer_destroy(dek_kek); + + return ret; +} diff --git a/srcs/key_manager.h b/srcs/key_manager.h new file mode 100644 index 0000000..ec84561 --- /dev/null +++ b/srcs/key_manager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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 + * + * + * @file key_manager.h + * @author Kyungwook Tak + * @version 1.0 + * @brief Serialize/deserialize crypto element and save/get to key-manager + */ +#ifndef __WAE_KEY_MANAGER_H +#define __WAE_KEY_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "web_app_enc.h" +#include "types.h" + +int save_to_key_manager(const char *pkg_id, wae_app_type_e type, const crypto_element_s *ce); +int get_from_key_manager(const char *pkg_id, wae_app_type_e type, crypto_element_s **pce); +int remove_from_key_manager(const char *pkg_id, wae_app_type_e type); + +bool is_app_deks_loaded_in_key_manager(); +int set_app_deks_loaded_to_key_manager(); +int clear_app_deks_loaded_from_key_manager(); + +#ifdef __cplusplus +} +#endif + +#endif /* __WAE_KEY_MANAGER_H */ diff --git a/srcs/types.c b/srcs/types.c new file mode 100644 index 0000000..fc76c33 --- /dev/null +++ b/srcs/types.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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 + * + * + * @file types.c + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Type definitions + */ +#include "types.h" + +#include +#include + +#include "wae_log.h" +#include "web_app_enc.h" + +const size_t MAX_MAP_ELEMENT_SIZE = 20; + +raw_buffer_s *buffer_create(size_t size) +{ + raw_buffer_s *rb = (raw_buffer_s *)malloc(sizeof(raw_buffer_s)); + if (rb == NULL) + return NULL; + + rb->buf = (unsigned char *)malloc(sizeof(unsigned char) * size); + if (rb->buf == NULL) { + free(rb); + return NULL; + } + + memset(rb->buf, 0x00, size); + + rb->size = size; + + return rb; +} + +raw_buffer_s *buffer_create_managed(unsigned char *buf, size_t size) +{ + if (buf == NULL || size == 0) + return NULL; + + raw_buffer_s *rb = (raw_buffer_s *)malloc(sizeof(raw_buffer_s)); + if (rb == NULL) + return NULL; + + rb->buf = buf; + rb->size = size; + + return rb; +} + +void buffer_destroy(raw_buffer_s *rb) +{ + if (rb == NULL) + return; + + free(rb->buf); + free(rb); +} + +bool is_buffer_valid(const raw_buffer_s *rb) +{ + return rb != NULL && rb->buf != NULL && rb->size != 0; +} + +crypto_element_s *crypto_element_create(raw_buffer_s *dek, raw_buffer_s *iv) +{ + if (dek == NULL || iv == NULL) + return NULL; + + crypto_element_s *ce = (crypto_element_s *)malloc(sizeof(crypto_element_s)); + if (ce == NULL) + return NULL; + + ce->dek = dek; + ce->iv = iv; + ce->is_migrated_app = false; + + return ce; +} + +void crypto_element_destroy(crypto_element_s *ce) +{ + if (ce == NULL) + return; + + buffer_destroy(ce->dek); + buffer_destroy(ce->iv); + free(ce); +} + +bool is_crypto_element_valid(const crypto_element_s *ce) +{ + return ce != NULL && is_buffer_valid(ce->dek) && is_buffer_valid(ce->iv); +} + +struct _crypto_element_map_s { + char *key; + crypto_element_s *value; + crypto_element_map_s *next; +}; + +static crypto_element_map_s *crypto_element_map_create() +{ + crypto_element_map_s *cem = (crypto_element_map_s *)malloc(sizeof(crypto_element_map_s)); + if (cem == NULL) + return NULL; + + cem->key = NULL; + cem->value = NULL; + cem->next = NULL; + + return cem; +} + +void crypto_element_map_destroy(crypto_element_map_s *cem) +{ + if (cem == NULL) + return; + + crypto_element_map_s *current = cem; + while (current) { + WAE_SLOGD("Destroy crypto element of key(%s)", current->key); + crypto_element_map_s *tmp = current->next; + + free(current->key); + crypto_element_destroy(current->value); + free(current); + + current = tmp; + } +} + +int crypto_element_map_add(crypto_element_map_s **map, + const char *key, crypto_element_s *value) +{ + if (map == NULL || key == NULL || !is_crypto_element_valid(value)) + return WAE_ERROR_INVALID_PARAMETER; + + crypto_element_map_s *last = *map; + size_t count = 0; + for (crypto_element_map_s *current = *map; current != NULL; current = current->next) { + if (strcmp(current->key, key) == 0) { + WAE_SLOGD("Update value to map on existing key(%s)", key); + crypto_element_destroy(current->value); + current->value = value; + return WAE_ERROR_NONE; + } + + ++count; + last = current; + } + + WAE_SLOGD("Add value to map on new key(%s)", key); + crypto_element_map_s *e = crypto_element_map_create(); + if (e == NULL) + return WAE_ERROR_MEMORY; + + e->key = strdup(key); + if (e->key == NULL) { + free(e); + return WAE_ERROR_MEMORY; + } + + e->value = value; + e->next = NULL; + + if (last == NULL) + *map = e; + else + last->next = e; + + if (count == MAX_MAP_ELEMENT_SIZE) { + WAE_SLOGD("Map size touched max! Remove one element from the front(%s)", + (*map)->key); + + crypto_element_map_s *next = (*map)->next; + + crypto_element_destroy((*map)->value); + free((*map)->key); + free(*map); + + *map = next; + } + + return WAE_ERROR_NONE; +} + +void crypto_element_map_remove(crypto_element_map_s **map, const char *key) +{ + if (map == NULL || key == NULL) + return; + + if (*map == NULL) { + WAE_SLOGD("Map is empty so remove operation ignored for key(%s)", key); + return; + } + + crypto_element_map_s *before = NULL; + crypto_element_map_s *current = *map; + while (current) { + if (strcmp(key, current->key) != 0) { + before = current; + current = current->next; + continue; + } + + WAE_SLOGD("Removing value mapped by key(%s)", key); + + crypto_element_map_s *next = current->next; + + free(current->key); + crypto_element_destroy(current->value); + free(current); + + if (before == NULL) + *map = next; + else + before->next = next; + + break; + } +} + +crypto_element_s *crypto_element_map_get(crypto_element_map_s *map, const char *key) +{ + if (map == NULL || key == NULL) { + WAE_SLOGD("Map is empty so nothing to get."); + return NULL; + } + + for (crypto_element_map_s *current = map; current != NULL; current = current->next) { + if (strcmp(key, current->key) == 0) { + WAE_SLOGD("Getting value mapped by key(%s)", key); + return current->value; + } + } + + WAE_SLOGD("Cannot get value mapped by key(%s). No mapped value!", key); + return NULL; +} diff --git a/srcs/types.h b/srcs/types.h new file mode 100644 index 0000000..7e27aeb --- /dev/null +++ b/srcs/types.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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 + * + * + * @file types.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Type definitions + */ +#ifndef __WAE_TYPES_H +#define __WAE_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct _raw_buffer_s { + unsigned char *buf; + size_t size; +} raw_buffer_s; + +typedef struct _crypto_element_s { + raw_buffer_s *dek; + raw_buffer_s *iv; + bool is_migrated_app; +} crypto_element_s; + +typedef struct _crypto_element_map_s crypto_element_map_s; + +raw_buffer_s *buffer_create(size_t size); +raw_buffer_s *buffer_create_managed(unsigned char *buf, size_t size); +void buffer_destroy(raw_buffer_s *); +bool is_buffer_valid(const raw_buffer_s *); + +crypto_element_s *crypto_element_create(raw_buffer_s *dek, raw_buffer_s *iv); +void crypto_element_destroy(crypto_element_s *c); +bool is_crypto_element_valid(const crypto_element_s *); + +extern const size_t MAX_MAP_ELEMENT_SIZE; + +void crypto_element_map_destroy(crypto_element_map_s *); +int crypto_element_map_add(crypto_element_map_s **map, const char *key, crypto_element_s *value); +void crypto_element_map_remove(crypto_element_map_s **map, const char *key); +crypto_element_s *crypto_element_map_get(crypto_element_map_s *map, const char *key); + +#ifdef __cplusplus +} +#endif + +#endif /* __WAE_TYPES_H */ diff --git a/srcs/web_app_enc.c b/srcs/web_app_enc.c index 083addf..22da420 100644 --- a/srcs/web_app_enc.c +++ b/srcs/web_app_enc.c @@ -26,6 +26,7 @@ #include "decrypt_migrated_wgt.h" #include "key_handler.h" #include "crypto_service.h" +#include "types.h" #include "wae_log.h" int _wae_encrypt_downloaded_web_application( @@ -37,57 +38,65 @@ int _wae_encrypt_downloaded_web_application( pencrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - // get APP_DEK. - // if not exists, create APP_DEK - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); + const crypto_element_s *e = NULL; + int ret = get_app_ce(pkg_id, app_type, false, &e); if (ret == WAE_ERROR_NO_KEY) - ret = create_app_dek(pkg_id, app_type, &dek, &dek_len); + ret = create_app_ce(pkg_id, app_type, &e); if (ret != WAE_ERROR_NONE) - goto error; + return ret; - // encrypt - ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; -error: - free(dek); + raw_buffer_s *_encrypted_data = NULL; + ret = encrypt_aes_cbc(e, &_data, &_encrypted_data); + if (ret != WAE_ERROR_NONE) + return ret; + + *pencrypted_data = _encrypted_data->buf; + *pencrypted_data_len = _encrypted_data->size; - return ret; + free(_encrypted_data); + + return WAE_ERROR_NONE; } int _wae_decrypt_downloaded_web_application(const char *pkg_id, wae_app_type_e app_type, const unsigned char *data, size_t data_len, unsigned char **pdecrypted_data, size_t *pdecrypted_data_len) { - if (pkg_id == NULL || data == NULL || data_len == 0 || pdecrypted_data == NULL || pdecrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_app_dek(pkg_id, app_type, &dek, &dek_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; + + const crypto_element_s *ce = NULL; + int ret = get_app_ce(pkg_id, app_type, true, &ce); + + if (ret != WAE_ERROR_NONE) + return ret; - if (app_type == WAE_DOWNLOADED_GLOBAL_APP && ret == WAE_ERROR_NO_KEY) { - WAE_SLOGI("app dek for decrypt downloaded app(%s) doesn't exist. This case would be " - "needed secure-storage data migration.", pkg_id); + raw_buffer_s *_decrypted_data = NULL; + if (ce->is_migrated_app) + ret = decrypt_by_old_ss_algo(ce, &_data, &_decrypted_data); + else + ret = decrypt_aes_cbc(ce, &_data, &_decrypted_data); - ret = decrypt_by_old_ss_algo(pkg_id, data, data_len, pdecrypted_data, pdecrypted_data_len); - goto error; // always go to error to skip decyprt_aes_cbc - } else if (ret != WAE_ERROR_NONE) { - goto error; - } + if (ret != WAE_ERROR_NONE) + return ret; - // decrypt - ret = decrypt_aes_cbc(dek, dek_len, data, data_len, pdecrypted_data, pdecrypted_data_len); + *pdecrypted_data = _decrypted_data->buf; + *pdecrypted_data_len = _decrypted_data->size; -error: - free(dek); + free(_decrypted_data); - return ret; + return WAE_ERROR_NONE; } int _wae_encrypt_preloaded_web_application(const char *pkg_id, @@ -98,23 +107,31 @@ int _wae_encrypt_preloaded_web_application(const char *pkg_id, pencrypted_data_len == NULL) return WAE_ERROR_INVALID_PARAMETER; - unsigned char *dek = NULL; - size_t dek_len = -1; - int ret = get_preloaded_app_dek(pkg_id, &dek, &dek_len); + const crypto_element_s *e = NULL; + int ret = get_preloaded_app_ce(pkg_id, &e); if (ret == WAE_ERROR_NO_KEY) - ret = create_preloaded_app_dek(pkg_id, &dek, &dek_len); + ret = create_preloaded_app_ce(pkg_id, &e); if (ret != WAE_ERROR_NONE) - goto error; + return ret; - // encrypt - ret = encrypt_aes_cbc(dek, dek_len, data, data_len, pencrypted_data, pencrypted_data_len); + raw_buffer_s _data; + _data.buf = (unsigned char *)data; + _data.size = data_len; -error: - free(dek); + raw_buffer_s *_encrypted_data = NULL; + ret = encrypt_aes_cbc(e, &_data, &_encrypted_data); + + if (ret != WAE_ERROR_NONE) + return ret; - return ret; + *pencrypted_data = _encrypted_data->buf; + *pencrypted_data_len = _encrypted_data->size; + + free(_encrypted_data); + + return WAE_ERROR_NONE; } int _wae_decrypt_preloaded_web_application(const char *pkg_id, wae_app_type_e app_type, @@ -150,8 +167,7 @@ int wae_decrypt_web_application(const char *pkg_id, wae_app_type_e app_type, data, data_len, pdecrypted_data, pdecrypted_data_len); } - int wae_remove_app_dek(const char *pkg_id, wae_app_type_e app_type) { - return remove_app_dek(pkg_id, app_type); + return remove_app_ce(pkg_id, app_type); } diff --git a/tests/internals.cpp b/tests/internals.cpp index 257447b..b5c106d 100644 --- a/tests/internals.cpp +++ b/tests/internals.cpp @@ -22,6 +22,7 @@ */ #include "web_app_enc.h" +#include #include #include @@ -32,6 +33,51 @@ #include "test-common.h" +namespace { + +using rb_raii = std::unique_ptr; +using ce_raii = std::unique_ptr; +using map_raii = std::unique_ptr; + +inline rb_raii _safe(raw_buffer_s *ptr) +{ + return rb_raii(ptr, buffer_destroy); +} + +inline ce_raii _safe(crypto_element_s *ptr) +{ + return ce_raii(ptr, crypto_element_destroy); +} + +inline map_raii _safe(crypto_element_map_s *ptr) +{ + return map_raii(ptr, crypto_element_map_destroy); +} + +crypto_element_s *_create_ce(void) +{ + raw_buffer_s *dek = buffer_create(32); + raw_buffer_s *iv = buffer_create(16); + crypto_element_s *ce = crypto_element_create(dek, iv); + + if (ce == nullptr) { + buffer_destroy(dek); + buffer_destroy(iv); + } else if (_get_random(ce->dek) != WAE_ERROR_NONE) { + crypto_element_destroy(ce); + ce = nullptr; + } else if (_get_random(ce->iv) != WAE_ERROR_NONE) { + crypto_element_destroy(ce); + ce = nullptr; + } + + BOOST_REQUIRE(ce != nullptr); + + return ce; +} + +} + BOOST_AUTO_TEST_SUITE(SYSTEM) BOOST_AUTO_TEST_SUITE(INTERNALS) @@ -78,29 +124,37 @@ BOOST_AUTO_TEST_CASE(encrypt_decrypt_app_dek) "+wIDAQAB\n" "-----END PUBLIC KEY-----"; - std::vector dek(32, 0); + raw_buffer_s *dek = buffer_create(32); + + auto _raii1 = _safe(dek); + + BOOST_REQUIRE_MESSAGE(dek != nullptr && dek->size == 32, "Failed to create buffer"); + BOOST_REQUIRE_MESSAGE(_get_random(dek) == WAE_ERROR_NONE, "Failed to get random"); + + raw_buffer_s pubkey; + + pubkey.buf = (unsigned char *)public_key; + pubkey.size = strlen(public_key); + + raw_buffer_s *encrypted = nullptr; + int ret = encrypt_app_dek(&pubkey, dek, &encrypted); - unsigned char *_encrypted = nullptr; - size_t _encrypted_len = 0; - int ret = encrypt_app_dek(reinterpret_cast(public_key), - strlen(public_key), dek.data(), dek.size(), &_encrypted, - &_encrypted_len); - auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); - free(_encrypted); + auto _raii2 = _safe(encrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_app_dek. ec: " << ret); - unsigned char *_decrypted = nullptr; - size_t _decrypted_len = 0; - ret = decrypt_app_dek(reinterpret_cast(private_key), - strlen(private_key), nullptr, encrypted.data(), encrypted.size(), - &_decrypted, &_decrypted_len); - auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); - free(_decrypted); + raw_buffer_s prikey; + prikey.buf = (unsigned char *)private_key; + prikey.size = strlen(private_key); + + raw_buffer_s *decrypted = nullptr; + ret = decrypt_app_dek(&prikey, nullptr, encrypted, &decrypted); + + auto _raii3 = _safe(decrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_app_dek. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == decrypted, + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(dek) == Wae::Test::bytes_to_hex(decrypted), "encrypted/decrypted dek isn't valid. " "dek(" << Wae::Test::bytes_to_hex(dek) << ") " "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); @@ -108,37 +162,32 @@ BOOST_AUTO_TEST_CASE(encrypt_decrypt_app_dek) BOOST_AUTO_TEST_CASE(encrypt_decrypt_aes_cbc) { - std::vector plaintext = { - 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', - 'o', 'q', '2', 'e', 'v', '0', '1', 'x' - }; + raw_buffer_s *data = buffer_create(16); + + auto _raii1 = _safe(data); - size_t dek_len = 32; - std::vector dek(dek_len, 0); + BOOST_REQUIRE_MESSAGE(data != nullptr && data->size == 16, "Failed to create buffer"); - int ret = _get_random(dek.size(), dek.data()); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get random"); + crypto_element_s *ce = _create_ce(); - unsigned char *_encrypted = nullptr; - size_t _encrypted_len = 0; - ret = encrypt_aes_cbc(dek.data(), dek.size(), plaintext.data(), plaintext.size(), - &_encrypted, &_encrypted_len); - auto encrypted = Wae::Test::bytearr_to_vec(_encrypted, _encrypted_len); - free(_encrypted); + auto _raii2 = _safe(ce); + + raw_buffer_s *encrypted = nullptr; + int ret = encrypt_aes_cbc(ce, data, &encrypted); + + auto _raii3 = _safe(encrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to encrypt_aes_cbc. ec: " << ret); - unsigned char *_decrypted = nullptr; - size_t _decrypted_len = 0; - ret = decrypt_aes_cbc(dek.data(), dek.size(), encrypted.data(), encrypted.size(), - &_decrypted, &_decrypted_len); - auto decrypted = Wae::Test::bytearr_to_vec(_decrypted, _decrypted_len); - free(_decrypted); + raw_buffer_s *decrypted = nullptr; + ret = decrypt_aes_cbc(ce, encrypted, &decrypted); + + auto _raii4 = _safe(decrypted); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to decrypt_aes_cbc. ec: " << ret); - BOOST_REQUIRE_MESSAGE(plaintext == decrypted, + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(data) == Wae::Test::bytes_to_hex(decrypted), "decrypted plaintext isn't valid. " - "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " + "plaintext(" << Wae::Test::bytes_to_hex(data) << ") " "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); } @@ -149,90 +198,79 @@ BOOST_AUTO_TEST_CASE(cache) const char *pkg3 = "pkg3"; const char *pkgDummy = "dummy"; - std::vector dek1(32, 1); - std::vector dek2(32, 2); - std::vector dek3(32, 3); + auto ce1 = _create_ce(); + auto ce2 = _create_ce(); + auto ce3 = _create_ce(); - _initialize_cache(); + crypto_element_map_s *map = nullptr; - _add_app_dek_to_cache(pkg1, dek1.data()); - _add_app_dek_to_cache(pkg2, dek2.data()); - _add_app_dek_to_cache(pkg3, dek3.data()); + int tmp = crypto_element_map_add(&map, pkg1, ce1); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - size_t dek_len = 32; - const unsigned char *_cached = _get_app_dek_from_cache(pkg1); - auto cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + tmp = crypto_element_map_add(&map, pkg2, ce2); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - BOOST_REQUIRE_MESSAGE(cached == dek1, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek1) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + tmp = crypto_element_map_add(&map, pkg3, ce3); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to add ce to map. ret: " << tmp); - _cached = _get_app_dek_from_cache(pkg2); - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg1) == ce1, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg2) == ce2, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg3) == ce3, + "cached ce has different address with actual."); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkgDummy) == nullptr, + "something returned with pkg dummy from map which should be null."); - BOOST_REQUIRE_MESSAGE(cached == dek2, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek2) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + crypto_element_map_remove(&map, pkg3); - _cached = _get_app_dek_from_cache(pkg3); - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg3) == nullptr, + "removed pkg(" << pkg3 << ") is returned from map which should be null."); - BOOST_REQUIRE_MESSAGE(cached == dek3, - "cached dek isn't valid! " - "dek(" << Wae::Test::bytes_to_hex(dek3) << ") " - "cached(" << Wae::Test::bytes_to_hex(cached) << ")"); + auto ce4 = _create_ce(); + tmp = crypto_element_map_add(&map, pkg1, ce4); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to update ce to map. ret: " << tmp); - _cached = _get_app_dek_from_cache(pkgDummy); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "wrong cached val is extracted by dummy pkg id. " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } + BOOST_REQUIRE_MESSAGE(crypto_element_map_get(map, pkg1) == ce4, + "cached ce has different address with actual."); - _remove_app_dek_from_cache(pkg3); + crypto_element_map_destroy(map); +} - _cached = _get_app_dek_from_cache(pkg3); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "app dek removed from cache but it's remained! " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } +BOOST_AUTO_TEST_CASE(cache_max) +{ + crypto_element_map_s *map = nullptr; - _initialize_cache(); + for (size_t i = 0; i < MAX_MAP_ELEMENT_SIZE + 1; ++i) { + BOOST_REQUIRE(crypto_element_map_add(&map, std::to_string(i).c_str(), _create_ce()) == WAE_ERROR_NONE); + } - _add_app_dek_to_cache(pkg1, dek1.data()); + BOOST_REQUIRE(crypto_element_map_get(map, "0") == nullptr); - _cached = nullptr; - _cached = _get_app_dek_from_cache(pkg2); - if (_cached) { - cached = Wae::Test::bytearr_to_vec(_cached, dek_len); - BOOST_REQUIRE_MESSAGE(false, - "cache is initialized but something is remained! " - "val(" << Wae::Test::bytes_to_hex(cached) << ")"); - } + crypto_element_map_destroy(map); } BOOST_AUTO_TEST_CASE(read_write_encrypted_app_dek) { const char *pkg_id = "write_test_pkg"; - std::vector dek(256, 0); + raw_buffer_s *dek = buffer_create(256); - int ret = _write_encrypted_app_dek_to_file(pkg_id, dek.data(), dek.size()); + auto raii1 = _safe(dek); + + BOOST_REQUIRE(dek != nullptr); + BOOST_REQUIRE(_get_random(dek) == WAE_ERROR_NONE); + + int ret = _write_encrypted_app_dek_to_file(pkg_id, dek); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to write_encrypted_app_dek_to_file. ec: " << ret); - unsigned char *_readed = nullptr; - size_t _readed_len = 0; - ret = _read_encrypted_app_dek_from_file(pkg_id, &_readed, &_readed_len); - auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + raw_buffer_s *readed = nullptr; + ret = _read_encrypted_app_dek_from_file(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to read_encrypted_app_dek_from_file. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == readed, + auto raii2 = _safe(readed); + + BOOST_REQUIRE_MESSAGE(Wae::Test::bytes_to_hex(dek) == Wae::Test::bytes_to_hex(readed), "dek isn't match after write/read file. " "dek(" << Wae::Test::bytes_to_hex(dek) << ") " "readed(" << Wae::Test::bytes_to_hex(readed) << ")"); @@ -242,35 +280,23 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_1) { const char *pkg_id = "TEST_PKG_ID_FOR_CREATE"; - unsigned char *_readed = nullptr; - size_t _readed_len = 0; - int ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); - auto readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + const crypto_element_s *readed = nullptr; + int ret = get_preloaded_app_ce(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NO_KEY, - "preloaded app dek to create is already exist. ec: " << ret); + "preloaded app ce to create is already exist. ec: " << ret); - unsigned char *_dek = nullptr; - size_t _dek_len = 0; - ret = create_preloaded_app_dek(pkg_id, &_dek, &_dek_len); - auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); + const crypto_element_s *ce = nullptr; + ret = create_preloaded_app_ce(pkg_id, &ce); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); - - _readed = nullptr; - ret = get_preloaded_app_dek(pkg_id, &_readed, &_readed_len); - readed = Wae::Test::bytearr_to_vec(_readed, _readed_len); - free(_readed); + "Failed to create_preloaded_app_ce. ec: " << ret); + ret = get_preloaded_app_ce(pkg_id, &readed); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to get_preloaded_app_dek. ec: " << ret); + "Failed to get_preloaded_app_ce. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek == readed, - "created/loaded dek is not matched! " - "created(" << Wae::Test::bytes_to_hex(dek) << ") " - "loaded(" << Wae::Test::bytes_to_hex(readed) << ")"); + BOOST_REQUIRE_MESSAGE(readed == ce, "cached ce address and actual is different!"); } BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) @@ -284,67 +310,42 @@ BOOST_AUTO_TEST_CASE(get_create_preloaded_app_dek_2) _get_preloaded_app_dek_file_path(pkg_id2, sizeof(path2), path2); // remove old test data - remove_app_dek(pkg_id1, WAE_PRELOADED_APP); - remove_app_dek(pkg_id2, WAE_PRELOADED_APP); + remove_app_ce(pkg_id1, WAE_PRELOADED_APP); + remove_app_ce(pkg_id2, WAE_PRELOADED_APP); unlink(path1); unlink(path2); - // create 2 deks for preloaded app - unsigned char *_dek1 = nullptr; - size_t _dek_len1 = 0; - int ret = create_preloaded_app_dek(pkg_id1, &_dek1, &_dek_len1); - auto dek1 = Wae::Test::bytearr_to_vec(_dek1, _dek_len1); - free(_dek1); - + // create 2 ces for preloaded app + const crypto_element_s *ce1 = nullptr; + int ret = create_preloaded_app_ce(pkg_id1, &ce1); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); - - unsigned char *_dek2 = nullptr; - size_t _dek_len2 = 0; - ret = create_preloaded_app_dek(pkg_id2, &_dek2, &_dek_len2); - auto dek2 = Wae::Test::bytearr_to_vec(_dek2, _dek_len2); - free(_dek2); + "Failed to create_preloaded_app_ce. ec: " << ret); + const crypto_element_s *ce2 = nullptr; + ret = create_preloaded_app_ce(pkg_id2, &ce2); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed to create_preloaded_app_dek. ec: " << ret); + "Failed to create_preloaded_app_ce. ec: " << ret); ret = load_preloaded_app_deks(true); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to load_preloaded_app_deks. ec: " << ret); - unsigned char *_readed1 = nullptr; - size_t _readed_len1 = 0; - ret = get_app_dek(pkg_id1, WAE_PRELOADED_APP, &_readed1, &_readed_len1); - auto readed1 = Wae::Test::bytearr_to_vec(_readed1, _readed_len1); - free(_readed1); - + const crypto_element_s *readed1 = nullptr; + ret = get_app_ce(pkg_id1, WAE_PRELOADED_APP, false, &readed1); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); - unsigned char *_readed2 = nullptr; - size_t _readed_len2 = 0; - ret = get_app_dek(pkg_id2, WAE_PRELOADED_APP, &_readed2, &_readed_len2); - auto readed2 = Wae::Test::bytearr_to_vec(_readed2, _readed_len2); - free(_readed2); - + const crypto_element_s *readed2 = nullptr; + ret = get_app_ce(pkg_id2, WAE_PRELOADED_APP, false, &readed2); BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << ret); - BOOST_REQUIRE_MESSAGE(dek1 == readed1, - "readed dek and original isn't matched! " - "original(" << Wae::Test::bytes_to_hex(dek1) << ") " - "readed(" << Wae::Test::bytes_to_hex(readed1) << ")"); + BOOST_REQUIRE_MESSAGE(readed1 == ce1, "cached ce and actual address is different!"); + BOOST_REQUIRE_MESSAGE(readed2 == ce2, "cached ce and actual address is different!"); - BOOST_REQUIRE_MESSAGE(dek2 == readed2, - "readed dek and original isn't matched! " - "original(" << Wae::Test::bytes_to_hex(dek2) << ") " - "readed(" << Wae::Test::bytes_to_hex(readed2) << ")"); + ret = remove_app_ce(pkg_id1, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); - ret = remove_app_dek(pkg_id1, WAE_PRELOADED_APP); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed remove app dek after used. ec: " << ret); - - ret = remove_app_dek(pkg_id2, WAE_PRELOADED_APP); - BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, - "Failed remove app dek after used. ec: " << ret); + ret = remove_app_ce(pkg_id2, WAE_PRELOADED_APP); + BOOST_REQUIRE_MESSAGE(ret == WAE_ERROR_NONE, "Failed remove app ce. ec: " << ret); } BOOST_AUTO_TEST_SUITE_END() // INTERNALS diff --git a/tests/non-normals.cpp b/tests/non-normals.cpp index 8667bfc..81c0173 100644 --- a/tests/non-normals.cpp +++ b/tests/non-normals.cpp @@ -32,12 +32,12 @@ BOOST_AUTO_TEST_SUITE(GLOBAL_APP) BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_GLOBAL_APP); + Wae::Test::add_get_remove_ce(WAE_DOWNLOADED_GLOBAL_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_DOWNLOADED_GLOBAL_APP); + Wae::Test::create_app_ce(WAE_DOWNLOADED_GLOBAL_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt) @@ -52,12 +52,12 @@ BOOST_AUTO_TEST_SUITE(PRELOADED_APP) BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_PRELOADED_APP); + Wae::Test::add_get_remove_ce(WAE_PRELOADED_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_PRELOADED_APP); + Wae::Test::create_app_ce(WAE_PRELOADED_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt) diff --git a/tests/normals.cpp b/tests/normals.cpp index 2ce272e..5d67910 100644 --- a/tests/normals.cpp +++ b/tests/normals.cpp @@ -32,12 +32,12 @@ BOOST_AUTO_TEST_SUITE(DOWNLOADED_APP); BOOST_AUTO_TEST_CASE(add_get_remove_dek) { - Wae::Test::add_get_remove_dek(WAE_DOWNLOADED_NORMAL_APP); + Wae::Test::add_get_remove_ce(WAE_DOWNLOADED_NORMAL_APP); } BOOST_AUTO_TEST_CASE(create_app_dek) { - Wae::Test::create_app_dek(WAE_DOWNLOADED_NORMAL_APP); + Wae::Test::create_app_ce(WAE_DOWNLOADED_NORMAL_APP); } BOOST_AUTO_TEST_CASE(encrypt_decrypt_normal_app) diff --git a/tests/test-common.cpp b/tests/test-common.cpp index 3e9e331..3157ca6 100644 --- a/tests/test-common.cpp +++ b/tests/test-common.cpp @@ -38,15 +38,42 @@ std::string bytes_to_hex(const std::vector &bytes) return ss.str(); } -std::vector bytearr_to_vec(const unsigned char *bytes, size_t len) +std::string bytes_to_hex(const raw_buffer_s *rb) { - if (bytes == nullptr || len == 0) + if (!is_buffer_valid(rb)) + return std::string(); + + return bytes_to_hex(rb->buf, rb->size); +} + +std::string bytes_to_hex(const unsigned char *ptr, size_t len) +{ + std::stringstream ss; + ss << std::hex; + + for (size_t i = 0; i < len; ++i) + ss << std::setw(2) << std::setfill('0') << static_cast(ptr[i]); + + return ss.str(); +} + +std::vector bytearr_to_vec(const raw_buffer_s *rb) +{ + if (!is_buffer_valid(rb)) + return std::vector(); + + return bytearr_to_vec(rb->buf, rb->size); +} + +std::vector bytearr_to_vec(const unsigned char *ptr, size_t len) +{ + if (ptr == nullptr || len == 0) return std::vector(); - std::vector vec; + std::vector vec(len); for (size_t i = 0; i < len; ++i) - vec.push_back(bytes[i]); + vec[i] = ptr[i]; return vec; } diff --git a/tests/test-common.h b/tests/test-common.h index 2c4c54e..57bf83b 100644 --- a/tests/test-common.h +++ b/tests/test-common.h @@ -28,6 +28,8 @@ #include "colour_log_formatter.h" +#include "types.h" + /* fixtures should be declared on outside of namespace */ struct TestConfig { TestConfig() @@ -45,7 +47,10 @@ namespace Wae { namespace Test { std::string bytes_to_hex(const std::vector &bytes); -std::vector bytearr_to_vec(const unsigned char *bytes, size_t len); +std::string bytes_to_hex(const unsigned char *ptr, size_t len); +std::string bytes_to_hex(const raw_buffer_s *rb); +std::vector bytearr_to_vec(const unsigned char *ptr, size_t len); +std::vector bytearr_to_vec(const raw_buffer_s *); } // namespace Test } // namespace Wae diff --git a/tests/test-helper.cpp b/tests/test-helper.cpp index 144299a..f303b75 100644 --- a/tests/test-helper.cpp +++ b/tests/test-helper.cpp @@ -25,78 +25,64 @@ #include "key_handler.h" #include "crypto_service.h" +#include "types.h" +#include "key_manager.h" #include "test-common.h" namespace Wae { namespace Test { -void add_get_remove_dek(wae_app_type_e app_type) +void add_get_remove_ce(wae_app_type_e app_type) { const char *pkg_id = "TEST_PKG_ID"; - std::vector dek(32, 0); - - BOOST_REQUIRE(_get_random(dek.size(), dek.data()) == WAE_ERROR_NONE); - - remove_app_dek(pkg_id, app_type); - - int tmp = _add_dek_to_key_manager(pkg_id, app_type, dek.data(), dek.size()); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to _add_dek_to_key_manager. ec: " << tmp); - - unsigned char *_stored_dek = nullptr; - size_t _stored_dek_len = 0; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to get_app_dek. ec: " << tmp); - - auto stored_dek = Wae::Test::bytearr_to_vec(_stored_dek, _stored_dek_len); - free(_stored_dek); - - BOOST_REQUIRE_MESSAGE(stored_dek == dek, "stored dek and dek isn't matched!"); - - tmp = remove_app_dek(pkg_id, app_type); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_dek. ec: " << tmp); - - _stored_dek = nullptr; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - if (_stored_dek) - free(_stored_dek); - - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, - "dek removed but it's remained still. ec: " << tmp); + const crypto_element_s *ce = nullptr; + int tmp = create_app_ce(pkg_id, app_type, &ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); + + const crypto_element_s *stored_ce = nullptr; + tmp = get_app_ce(pkg_id, app_type, true, &stored_ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); + + BOOST_REQUIRE_MESSAGE(ce == stored_ce, + "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); + + tmp = remove_app_ce(pkg_id, app_type); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); + + if (app_type == WAE_DOWNLOADED_GLOBAL_APP) { + tmp = get_app_ce(pkg_id, app_type, true, &stored_ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE && stored_ce->is_migrated_app, + "when getting app ce which is there isn't, it should be migrated case! " + "ret("<< tmp << ") and is_migrated_app(" << stored_ce->is_migrated_app << ")"); + } else { + tmp = get_app_ce(pkg_id, app_type, false, &stored_ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NO_KEY, + "removed app ce is still remaining. ret(" << tmp << ")"); + } } -void create_app_dek(wae_app_type_e app_type) +void create_app_ce(wae_app_type_e app_type) { const char *pkg_id = "TEST_PKG_ID"; - remove_app_dek(pkg_id, app_type); - - unsigned char *_dek = nullptr; - size_t _dek_len = 0; + remove_app_ce(pkg_id, app_type); - int tmp = create_app_dek(pkg_id, app_type, &_dek, &_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, - "Failed to create_app_dek. ec: " << tmp); + const crypto_element_s *ce = nullptr; - auto dek = Wae::Test::bytearr_to_vec(_dek, _dek_len); - free(_dek); + int tmp = create_app_ce(pkg_id, app_type, &ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to create_app_ce. ec: " << tmp); - unsigned char *_stored_dek = nullptr; - size_t _stored_dek_len = 0; - tmp = get_app_dek(pkg_id, app_type, &_stored_dek, &_stored_dek_len); - BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_dek. ec: " << tmp); - auto stored_dek = bytearr_to_vec(_stored_dek, _stored_dek_len); - free(_stored_dek); + const crypto_element_s *stored_ce = nullptr; + tmp = get_app_ce(pkg_id, app_type, false, &stored_ce); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to get_app_ce. ec: " << tmp); - BOOST_REQUIRE_MESSAGE(stored_dek == dek, - "stored dek and dek isn't matched! " - "stored_dek(" << Wae::Test::bytes_to_hex(stored_dek) << ") " - "dek(" << Wae::Test::bytes_to_hex(dek) << ")"); + BOOST_REQUIRE_MESSAGE(ce == stored_ce, + "ce(" << ce << ") and cached ce(" << stored_ce << ") pointer addr is different!"); - remove_app_dek(pkg_id, app_type); + tmp = remove_app_ce(pkg_id, app_type); + BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, "Failed to remove_app_ce. ec: " << tmp); } void encrypt_decrypt_web_app(wae_app_type_e app_type) @@ -125,7 +111,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) wae_remove_app_dek(pkg_id, app_type); if (app_type == WAE_PRELOADED_APP) - _clear_app_deks_loaded(); + clear_app_deks_loaded_from_key_manager(); std::vector plaintext = { 'a', 'b', 'c', 'a', 'b', 'c', 'x', 'y', @@ -150,7 +136,7 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) auto encrypted = bytearr_to_vec(_encrypted, _enc_len); free(_encrypted); - _remove_app_dek_from_cache(pkg_id); + _remove_app_ce_from_cache(pkg_id); if (app_type == WAE_PRELOADED_APP) load_preloaded_app_deks(true); @@ -166,8 +152,8 @@ void encrypt_decrypt_web_app(wae_app_type_e app_type) BOOST_REQUIRE_MESSAGE(plaintext == decrypted, "plaintext and decrypted isn't matched! " - "plaintext(" << Wae::Test::bytes_to_hex(plaintext) << ") " - "decrypted(" << Wae::Test::bytes_to_hex(decrypted) << ")"); + "plaintext(" << bytes_to_hex(plaintext) << ") " + "decrypted(" << bytes_to_hex(decrypted) << ")"); tmp = wae_remove_app_dek(pkg_id, app_type); BOOST_REQUIRE_MESSAGE(tmp == WAE_ERROR_NONE, diff --git a/tests/test-helper.h b/tests/test-helper.h index 132ceae..c0c77f6 100644 --- a/tests/test-helper.h +++ b/tests/test-helper.h @@ -25,8 +25,8 @@ namespace Wae { namespace Test { -void add_get_remove_dek(wae_app_type_e app_type); -void create_app_dek(wae_app_type_e app_type); +void add_get_remove_ce(wae_app_type_e app_type); +void create_app_ce(wae_app_type_e app_type); void encrypt_decrypt_web_app(wae_app_type_e app_type); } // namespace Test -- 2.7.4