blob: bfa5616f1c251d4b4f46762744e64804949d94ed [file]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* 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.
*/
#define TLOG_TAG "hwaes_unittest"
#include <stdlib.h>
#include <string.h>
#include <lib/hwaes/hwaes.h>
#include <lib/hwkey/hwkey.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <trusty/memref.h>
#include <trusty_unittest.h>
#include <uapi/err.h>
#define AUX_PAGE_SIZE() getauxval(AT_PAGESZ)
#if SIMULATION
#define MAX_TRY_TIMES 3
#else
#define MAX_TRY_TIMES 1000
#endif
#define UNUSED_HWAES_ERROR_CODE HWAES_NO_ERROR
#define HWAES_GCM_IV_SIZE 12
#if WITH_HWCRYPTO_UNITTEST
#define DISABLED_WITHOUT_HWCRYPTO_UNITTEST(name) name
#else
#define DISABLED_WITHOUT_HWCRYPTO_UNITTEST(name) DISABLED_##name
#endif
/**
* struct hwaes_iov - an wrapper of an array of iovec.
* @iovs: array of iovec.
* @num_iov: number of iovec.
* @total_len: total length of the tipc message.
*/
struct hwaes_iov {
struct iovec iov[TIPC_MAX_MSG_PARTS];
size_t num_iov;
size_t total_len;
};
/**
* struct hwaes_shm - an wrapper of an array of shared memory handles.
* @handles: array of shared memory handles.
* @num_handles: number of shared memory handles.
*/
struct hwaes_shm {
handle_t handles[HWAES_MAX_NUM_HANDLES];
size_t num_handles;
};
struct test_vector {
uint32_t mode;
struct hwcrypt_arg_in key;
struct hwcrypt_arg_in iv;
struct hwcrypt_arg_in aad;
struct hwcrypt_arg_in tag;
struct hwcrypt_arg_in plaintext;
struct hwcrypt_arg_in ciphertext;
};
/*
* Test vectors are from boringssl cipher_tests.txt which are in turn taken from
* the GCM spec at
* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
*
* We are intentionally not testing non-standard IV lengths because we don't
* support this (yet).
*/
/* AES 128 GCM */
static const uint8_t gcm_test1_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test1_iv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test1_plaintext[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test1_ciphertext[] = {
0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78};
static const uint8_t gcm_test1_aad[] = {};
static const uint8_t gcm_test1_tag[] = {0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec,
0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2,
0x12, 0x57, 0xbd, 0xdf};
static const uint8_t gcm_test2_key[] = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65,
0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08};
static const uint8_t gcm_test2_iv[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88};
static const uint8_t gcm_test2_plaintext[] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09,
0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34,
0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c,
0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24,
0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6,
0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55};
static const uint8_t gcm_test2_ciphertext[] = {
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21,
0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02,
0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21,
0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a,
0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac,
0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85};
static const uint8_t gcm_test2_aad[] = {};
static const uint8_t gcm_test2_tag[] = {0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd,
0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd,
0x2b, 0xa6, 0xfa, 0xb4};
static const uint8_t gcm_test3_key[] = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65,
0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08};
static const uint8_t gcm_test3_iv[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88};
static const uint8_t gcm_test3_plaintext[] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5,
0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39};
static const uint8_t gcm_test3_ciphertext[] = {
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7,
0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2,
0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91};
static const uint8_t gcm_test3_aad[] = {
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2};
static const uint8_t gcm_test3_tag[] = {0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21,
0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a,
0xe7, 0x12, 0x1a, 0x47};
/* AES 256 GCM */
static const uint8_t gcm_test4_key[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test4_iv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test4_plaintext[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t gcm_test4_ciphertext[] = {
0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18};
static const uint8_t gcm_test4_aad[] = {};
static const uint8_t gcm_test4_tag[] = {0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99,
0x6b, 0xf0, 0x26, 0x5b, 0x98, 0xb5,
0xd4, 0x8a, 0xb9, 0x19};
static const uint8_t gcm_test5_key[] = {
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65,
0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08};
static const uint8_t gcm_test5_iv[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88};
static const uint8_t gcm_test5_plaintext[] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09,
0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34,
0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c,
0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24,
0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6,
0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55};
static const uint8_t gcm_test5_ciphertext[] = {
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37,
0xa3, 0x2a, 0x84, 0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5,
0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 0x8c,
0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0, 0x8b, 0x10,
0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a,
0x0a, 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad};
static const uint8_t gcm_test5_aad[] = {};
static const uint8_t gcm_test5_tag[] = {0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34,
0x71, 0xbd, 0xec, 0x1a, 0x50, 0x22,
0x70, 0xe3, 0xcc, 0x6c};
static const uint8_t gcm_test6_key[] = {
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f,
0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65,
0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08};
static const uint8_t gcm_test6_iv[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce,
0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88};
static const uint8_t gcm_test6_plaintext[] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5,
0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95,
0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39};
static const uint8_t gcm_test6_ciphertext[] = {
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3,
0x2a, 0x84, 0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48,
0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 0xbc, 0xc9, 0xf6, 0x62};
static const uint8_t gcm_test6_aad[] = {
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2};
static const uint8_t gcm_test6_tag[] = {0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e,
0x17, 0x68, 0xcd, 0xdf, 0x88, 0x53,
0xbb, 0x2d, 0x55, 0x1b};
/* clang-format off */
#define TV_DATA(name_, field_) \
.field_ = {.data_ptr = &name_##_##field_, .len = sizeof(name_##_##field_)}
#define TV(mode_, name_) \
{ \
.mode = mode_, \
TV_DATA(name_, key), \
TV_DATA(name_, iv), \
TV_DATA(name_, aad), \
TV_DATA(name_, tag), \
TV_DATA(name_, ciphertext), \
TV_DATA(name_, plaintext) \
}
/* clang-format on */
static const struct test_vector vectors[] = {
TV(HWAES_GCM_MODE, gcm_test1), TV(HWAES_GCM_MODE, gcm_test2),
TV(HWAES_GCM_MODE, gcm_test3), TV(HWAES_GCM_MODE, gcm_test4),
TV(HWAES_GCM_MODE, gcm_test5), TV(HWAES_GCM_MODE, gcm_test6),
};
static void parse_vector(const struct test_vector* vector,
struct hwcrypt_shm_hd* shm_handle,
struct hwcrypt_args* args,
int encrypt) {
args->key_type = HWAES_PLAINTEXT_KEY;
args->padding = HWAES_NO_PADDING;
args->mode = vector->mode;
args->key = vector->key;
args->iv = vector->iv;
args->aad = vector->aad;
if (encrypt) {
args->text_in = vector->plaintext;
} else {
args->text_in = vector->ciphertext;
args->tag_in = vector->tag;
}
uint8_t* base = (uint8_t*)shm_handle->base;
args->text_out.data_ptr = base;
args->text_out.len = args->text_in.len;
args->text_out.shm_hd_ptr = shm_handle;
if (encrypt && vector->tag.len > 0) {
args->tag_out.data_ptr = base + args->text_out.len;
args->tag_out.len = vector->tag.len;
args->tag_out.shm_hd_ptr = shm_handle;
}
}
static const uint8_t hwaes_key[32];
static const uint8_t hwaes_iv[16];
static const uint8_t hwaes_cbc_plaintext[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t hwaes_cbc_ciphertext[] = {
0xdc, 0x95, 0xc0, 0x78, 0xa2, 0x40, 0x89, 0x89, 0xad, 0x48, 0xa2,
0x14, 0x92, 0x84, 0x20, 0x87, 0x08, 0xc3, 0x74, 0x84, 0x8c, 0x22,
0x82, 0x33, 0xc2, 0xb3, 0x4f, 0x33, 0x2b, 0xd2, 0xe9, 0xd3};
typedef struct hwaes {
hwaes_session_t hwaes_session;
handle_t memref;
void* shm_base;
size_t shm_len;
struct hwcrypt_shm_hd shm_hd;
struct hwcrypt_args args_encrypt;
struct hwcrypt_args args_decrypt;
struct hwaes_req req_hdr;
struct hwaes_aes_req cmd_hdr;
struct hwaes_shm_desc shm_descs[HWAES_MAX_NUM_HANDLES];
struct hwaes_iov req_iov;
struct hwaes_shm req_shm;
} hwaes_t;
static void make_bad_request(handle_t channel,
struct hwaes_iov* req_iov,
struct hwaes_shm* req_shm,
bool expect_reply,
uint32_t expect_error) {
struct uevent event;
ipc_msg_info_t msg_inf;
bool got_msg = false;
ipc_msg_t req_msg = {
.iov = req_iov->iov,
.num_iov = req_iov->num_iov,
.handles = req_shm->handles,
.num_handles = req_shm->num_handles,
};
int rc;
rc = send_msg(channel, &req_msg);
ASSERT_EQ((size_t)rc, req_iov->total_len);
rc = wait(channel, &event, INFINITE_TIME);
ASSERT_EQ(rc, NO_ERROR);
if (expect_reply) {
ASSERT_NE(event.event & IPC_HANDLE_POLL_MSG, 0);
} else {
ASSERT_EQ(event.event, IPC_HANDLE_POLL_HUP);
return;
}
rc = get_msg(channel, &msg_inf);
ASSERT_EQ(rc, NO_ERROR);
got_msg = true;
ASSERT_EQ(msg_inf.len, sizeof(struct hwaes_resp));
struct hwaes_resp resp_hdr = {0};
struct iovec resp_iov = {
.iov_base = (void*)&resp_hdr,
.iov_len = sizeof(resp_hdr),
};
ipc_msg_t resp_msg = {
.iov = &resp_iov,
.num_iov = 1,
.handles = NULL,
.num_handles = 0,
};
rc = read_msg(channel, msg_inf.id, 0, &resp_msg);
ASSERT_EQ((size_t)rc, msg_inf.len);
struct hwaes_req* req_hdr = (struct hwaes_req*)req_iov->iov[0].iov_base;
ASSERT_EQ(resp_hdr.cmd, req_hdr->cmd | HWAES_RESP_BIT);
put_msg(channel, msg_inf.id);
EXPECT_EQ(expect_error, resp_hdr.result);
return;
test_abort:
if (got_msg) {
put_msg(channel, msg_inf.id);
}
return;
}
TEST_F_SETUP(hwaes) {
int rc;
void* shm_base;
size_t shm_len = AUX_PAGE_SIZE();
_state->hwaes_session = INVALID_IPC_HANDLE;
_state->memref = INVALID_IPC_HANDLE;
_state->shm_base = NULL;
rc = hwaes_open(&_state->hwaes_session);
ASSERT_EQ(rc, 0);
shm_base = memalign(AUX_PAGE_SIZE(), shm_len);
ASSERT_NE(NULL, shm_base, "fail to allocate shared memory");
rc = memref_create(shm_base, shm_len, PROT_READ | PROT_WRITE);
ASSERT_GE(rc, 0);
_state->memref = (handle_t)rc;
_state->shm_base = shm_base;
_state->shm_len = shm_len;
memset(_state->shm_base, 0, _state->shm_len);
memcpy(_state->shm_base, hwaes_cbc_plaintext, sizeof(hwaes_cbc_plaintext));
_state->shm_hd = (struct hwcrypt_shm_hd){
.handle = _state->memref,
.base = _state->shm_base,
.size = _state->shm_len,
};
_state->args_encrypt = (struct hwcrypt_args){
.key =
{
.data_ptr = hwaes_key,
.len = sizeof(hwaes_key),
},
.iv =
{
.data_ptr = hwaes_iv,
.len = sizeof(hwaes_iv),
},
.text_in =
{
.data_ptr = _state->shm_base,
.len = sizeof(hwaes_cbc_plaintext),
.shm_hd_ptr = &_state->shm_hd,
},
.text_out =
{
.data_ptr = _state->shm_base,
.len = sizeof(hwaes_cbc_ciphertext),
.shm_hd_ptr = &_state->shm_hd,
},
.key_type = HWAES_PLAINTEXT_KEY,
.padding = HWAES_NO_PADDING,
.mode = HWAES_CBC_MODE,
};
_state->args_decrypt = (struct hwcrypt_args){
.key =
{
.data_ptr = hwaes_key,
.len = sizeof(hwaes_key),
},
.iv =
{
.data_ptr = hwaes_iv,
.len = sizeof(hwaes_iv),
},
.text_in =
{
.data_ptr = _state->shm_base,
.len = sizeof(hwaes_cbc_ciphertext),
.shm_hd_ptr = &_state->shm_hd,
},
.text_out =
{
.data_ptr = _state->shm_base,
.len = sizeof(hwaes_cbc_plaintext),
.shm_hd_ptr = &_state->shm_hd,
},
.key_type = HWAES_PLAINTEXT_KEY,
.padding = HWAES_NO_PADDING,
.mode = HWAES_CBC_MODE,
};
_state->req_hdr = (struct hwaes_req){
.cmd = HWAES_AES,
};
_state->cmd_hdr = (struct hwaes_aes_req){
.key =
(struct hwaes_data_desc){
.len = sizeof(hwaes_key),
.shm_idx = 0,
},
.num_handles = 1,
};
_state->shm_descs[0] = (struct hwaes_shm_desc){.size = _state->shm_len};
_state->req_iov = (struct hwaes_iov){
.iov =
{
{&_state->req_hdr, sizeof(_state->req_hdr)},
{&_state->cmd_hdr, sizeof(_state->cmd_hdr)},
{&_state->shm_descs, sizeof(struct hwaes_shm_desc)},
},
.num_iov = 3,
.total_len = sizeof(_state->req_hdr) + sizeof(_state->cmd_hdr) +
sizeof(struct hwaes_shm_desc),
};
_state->req_shm = (struct hwaes_shm){
.handles = {_state->memref},
.num_handles = 1,
};
test_abort:;
}
TEST_F_TEARDOWN(hwaes) {
close(_state->hwaes_session);
close(_state->memref);
free(_state->shm_base);
}
TEST_F(hwaes, GenericInvalidSession) {
hwaes_session_t invalid = INVALID_IPC_HANDLE;
struct hwcrypt_args args = {};
// should fail immediately
int rc = hwaes_encrypt(invalid, &args);
EXPECT_EQ(ERR_BAD_HANDLE, rc, "generic - bad handle");
}
TEST_F(hwaes, RequestHeaderReservedNotZero) {
_state->req_hdr.reserved = 1U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
false, UNUSED_HWAES_ERROR_CODE);
}
TEST_F(hwaes, CommandUnsupported) {
_state->req_hdr.cmd = 0U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_NOT_IMPLEMENTED);
}
TEST_F(hwaes, CommandHeaderReservedNotZero) {
_state->cmd_hdr.reserved = 1U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
false, UNUSED_HWAES_ERROR_CODE);
}
TEST_F(hwaes, SharedMemoryHandlesNumberConflict) {
_state->cmd_hdr.num_handles += 1;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
false, UNUSED_HWAES_ERROR_CODE);
}
TEST_F(hwaes, SharedMemoryDescriptorReservedNotZero) {
_state->shm_descs[0].reserved = 1U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_IO);
}
TEST_F(hwaes, SharedMemoryDescriptorWrongWriteFlag) {
_state->shm_descs[0].write = 2U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_IO);
}
TEST_F(hwaes, SharedMemoryDescriptorBadSize) {
/* size is not page aligned */
_state->shm_descs[0].size = 4;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_INVALID_ARGS);
}
TEST_F(hwaes, DataDescriptorReservedNotZero) {
_state->cmd_hdr.key.reserved = 1U;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_IO);
}
TEST_F(hwaes, DataDescriptorBadLength) {
_state->cmd_hdr.key.len = _state->shm_len + 1ULL;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_INVALID_ARGS);
}
TEST_F(hwaes, DataDescriptorBadSharedMemoryHandleIndex) {
_state->cmd_hdr.key.shm_idx = 4;
make_bad_request(_state->hwaes_session, &_state->req_iov, &_state->req_shm,
true, HWAES_ERR_IO);
}
TEST_F(hwaes, InvalidSharedMemoryHandle) {
struct hwcrypt_shm_hd bad_shm_hd = {
.handle = INVALID_IPC_HANDLE,
.base = _state->shm_base,
.size = _state->shm_len,
};
_state->args_encrypt.text_in.shm_hd_ptr = &bad_shm_hd;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_BAD_HANDLE, rc, "expect bad handle error");
}
TEST_F(hwaes, BadSharedMemorySize) {
struct hwcrypt_shm_hd bad_shm_hd = {
.handle = _state->memref,
.base = _state->shm_base,
.size = 0,
};
_state->args_encrypt.text_in.shm_hd_ptr = &bad_shm_hd;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect bad length error");
}
TEST_F(hwaes, KeyArgumentNotSetEncrypt) {
_state->args_encrypt.key.len = 0;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, IVArgumentNotSetEncrypt) {
_state->args_encrypt.iv.len = 0;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, TextInArgumentNotSetEncrypt) {
_state->args_encrypt.text_in.len = 0;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, TextOutArgumentNotSetEncrypt) {
_state->args_encrypt.text_out.len = 0;
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, KeyArgumentNotSetDecrypt) {
_state->args_decrypt.key.len = 0;
int rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, IVArgumentNotSetDecrypt) {
_state->args_decrypt.iv.len = 0;
int rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, TextInArgumentNotSetDecrypt) {
_state->args_decrypt.text_in.len = 0;
int rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, TextOutArgumentNotSetDecrypt) {
_state->args_decrypt.text_out.len = 0;
int rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "expect invalid_args error");
}
TEST_F(hwaes, EncryptionDecryptionCBC) {
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(NO_ERROR, rc, "encryption - cbc mode");
rc = memcmp(_state->shm_base, hwaes_cbc_ciphertext,
sizeof(hwaes_cbc_ciphertext));
EXPECT_EQ(0, rc, "wrong encryption result");
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(NO_ERROR, rc, "decryption - cbc mode");
rc = memcmp(_state->shm_base, hwaes_cbc_plaintext,
sizeof(hwaes_cbc_plaintext));
EXPECT_EQ(0, rc, "wrong decryption result");
}
TEST_F(hwaes, EncryptionDecryptionCBCNoSHM) {
uint8_t buf[sizeof(hwaes_cbc_plaintext)] = {0};
memcpy(buf, hwaes_cbc_plaintext, sizeof(hwaes_cbc_plaintext));
_state->args_encrypt.text_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
_state->args_encrypt.text_out = (struct hwcrypt_arg_out){
.data_ptr = buf,
.len = sizeof(buf),
};
_state->args_decrypt.text_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
_state->args_decrypt.text_out = (struct hwcrypt_arg_out){
.data_ptr = buf,
.len = sizeof(buf),
};
int rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(NO_ERROR, rc, "encryption - cbc mode");
rc = memcmp(buf, hwaes_cbc_ciphertext, sizeof(hwaes_cbc_ciphertext));
EXPECT_EQ(0, rc, "wrong encryption result");
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(NO_ERROR, rc, "decryption - cbc mode");
rc = memcmp(buf, hwaes_cbc_plaintext, sizeof(hwaes_cbc_plaintext));
EXPECT_EQ(0, rc, "wrong decryption result");
}
TEST_F(hwaes, RunEncryptMany) {
int rc;
for (size_t i = 0; i < MAX_TRY_TIMES; i++) {
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
ASSERT_EQ(NO_ERROR, rc, "encryption - in loop");
}
memcpy(_state->shm_base, hwaes_cbc_plaintext, sizeof(hwaes_cbc_plaintext));
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(NO_ERROR, rc, "encryption - final round");
rc = memcmp(_state->shm_base, hwaes_cbc_ciphertext,
sizeof(hwaes_cbc_ciphertext));
EXPECT_EQ(0, rc, "wrong encryption result");
test_abort:;
}
TEST_F(hwaes, EncryptVectors) {
const struct test_vector* vector = vectors;
for (unsigned long i = 0; i < countof(vectors); ++i, ++vector) {
memset(_state->shm_base, 0, _state->shm_len);
struct hwcrypt_args args = {};
struct hwcrypt_shm_hd shm_hd = {
.handle = _state->memref,
.base = _state->shm_base,
.size = _state->shm_len,
};
parse_vector(vector, &shm_hd, &args, 1 /* encrypt */);
int rc = hwaes_encrypt(_state->hwaes_session, &args);
EXPECT_EQ(NO_ERROR, rc, "Encryption failed for test vector %lu\n", i);
rc = memcmp(_state->shm_base, vector->ciphertext.data_ptr,
vector->ciphertext.len);
EXPECT_EQ(0, rc, "wrong ciphertext result");
if (vector->tag.len > 0) {
rc = memcmp((uint8_t*)_state->shm_base + vector->ciphertext.len,
vector->tag.data_ptr, vector->tag.len);
EXPECT_EQ(0, rc, "wrong encryption tag result");
}
}
test_abort:;
}
TEST_F(hwaes, DecryptVectors) {
const struct test_vector* vector = vectors;
for (unsigned long i = 0; i < countof(vectors); ++i, ++vector) {
memset(_state->shm_base, 0, _state->shm_len);
struct hwcrypt_args args = {};
struct hwcrypt_shm_hd shm_hd = {
.handle = _state->memref,
.base = _state->shm_base,
.size = _state->shm_len,
};
parse_vector(vector, &shm_hd, &args, 0 /* decrypt */);
int rc = hwaes_decrypt(_state->hwaes_session, &args);
EXPECT_EQ(NO_ERROR, rc, "Decryption failed for test vector %lu\n", i);
rc = memcmp(_state->shm_base, vector->plaintext.data_ptr,
vector->plaintext.len);
EXPECT_EQ(0, rc, "wrong decryption result");
}
test_abort:;
}
TEST_F(hwaes, InvalidAEADArgsForCBC) {
int rc;
uint8_t buf[sizeof(hwaes_cbc_plaintext)] = {0};
_state->args_encrypt.aad = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported AAD");
_state->args_encrypt.aad = (struct hwcrypt_arg_in){};
_state->args_encrypt.tag_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported tag");
_state->args_encrypt.tag_in = (struct hwcrypt_arg_in){};
_state->args_encrypt.tag_out = (struct hwcrypt_arg_out){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported tag");
_state->args_decrypt.aad = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported AAD");
_state->args_decrypt.aad = (struct hwcrypt_arg_in){};
_state->args_decrypt.tag_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported tag");
_state->args_decrypt.tag_in = (struct hwcrypt_arg_in){};
_state->args_decrypt.tag_out = (struct hwcrypt_arg_out){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "unsupported tag");
}
TEST_F(hwaes, InvalidGCMTagArgs) {
int rc;
uint8_t buf[16] = {0};
_state->args_encrypt.mode = HWAES_GCM_MODE;
ASSERT_LE(HWAES_GCM_IV_SIZE, _state->args_encrypt.iv.len,
"IV length too short");
_state->args_encrypt.iv.len = HWAES_GCM_IV_SIZE;
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "missing tag output for GCM");
_state->args_encrypt.tag_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "wrong tag direction for encryption");
_state->args_decrypt.mode = HWAES_GCM_MODE;
ASSERT_LE(HWAES_GCM_IV_SIZE, _state->args_decrypt.iv.len,
"IV length too short");
_state->args_decrypt.iv.len = HWAES_GCM_IV_SIZE;
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "missing tag input for GCM");
_state->args_decrypt.tag_in = (struct hwcrypt_arg_in){
.data_ptr = buf,
.len = sizeof(buf),
};
_state->args_decrypt.tag_out = (struct hwcrypt_arg_out){
.data_ptr = buf,
.len = sizeof(buf),
};
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "wrong tag direction for decryption");
test_abort:;
}
static const uint8_t opaque_key_ciphertext[] = {
0x8c, 0xc8, 0xc0, 0xc7, 0x76, 0x57, 0xb4, 0x4f, 0x22, 0xd3, 0x33,
0x2e, 0x6f, 0x23, 0x92, 0x51, 0x21, 0x69, 0x30, 0xff, 0x84, 0x88,
0x4c, 0x38, 0x04, 0xe5, 0x17, 0xad, 0x5c, 0x08, 0x87, 0xfc,
};
#define HWKEY_OPAQUE_KEY_ID "com.android.trusty.hwaes.unittest.opaque_handle"
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(EncryptWithOpaqueKey)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE] = {0};
uint32_t key_handle_size = HWKEY_OPAQUE_HANDLE_MAX_SIZE;
rc = hwkey_get_keyslot_data(hwkey_session, HWKEY_OPAQUE_KEY_ID, key_handle,
&key_handle_size);
EXPECT_EQ(NO_ERROR, rc, "Could not get opaque key handle");
EXPECT_LE(key_handle_size, HWKEY_OPAQUE_HANDLE_MAX_SIZE,
"Wrong handle size");
_state->args_encrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_encrypt.key.data_ptr = key_handle;
_state->args_encrypt.key.len = key_handle_size;
_state->args_encrypt.key.shm_hd_ptr = NULL;
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(NO_ERROR, rc, "opaque encryption - cbc mode");
rc = memcmp(_state->shm_base, opaque_key_ciphertext,
sizeof(opaque_key_ciphertext));
EXPECT_EQ(0, rc, "wrong encryption result");
hwkey_close(hwkey_session);
test_abort:;
}
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(DecryptWithOpaqueKey)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE] = {0};
uint32_t key_handle_size = HWKEY_OPAQUE_HANDLE_MAX_SIZE;
rc = hwkey_get_keyslot_data(hwkey_session, HWKEY_OPAQUE_KEY_ID, key_handle,
&key_handle_size);
EXPECT_EQ(NO_ERROR, rc, "Could not get opaque key handle");
EXPECT_LE(key_handle_size, HWKEY_OPAQUE_HANDLE_MAX_SIZE,
"Wrong handle size");
_state->args_decrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_decrypt.key.data_ptr = key_handle;
_state->args_decrypt.key.len = key_handle_size;
_state->args_decrypt.key.shm_hd_ptr = NULL;
memcpy(_state->shm_base, opaque_key_ciphertext,
sizeof(opaque_key_ciphertext));
_state->args_decrypt.text_in.data_ptr = _state->shm_base;
_state->args_decrypt.text_in.len = sizeof(opaque_key_ciphertext);
_state->args_decrypt.text_in.shm_hd_ptr = &_state->shm_hd;
rc = hwaes_decrypt(_state->hwaes_session, &_state->args_decrypt);
EXPECT_EQ(NO_ERROR, rc, "opaque decryption - cbc mode");
rc = memcmp(_state->shm_base, hwaes_cbc_plaintext,
sizeof(hwaes_cbc_plaintext));
EXPECT_EQ(0, rc, "wrong decryption result");
hwkey_close(hwkey_session);
test_abort:;
}
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(RunOpaqueEncryptMany)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE] = {0};
uint32_t key_handle_size = HWKEY_OPAQUE_HANDLE_MAX_SIZE;
rc = hwkey_get_keyslot_data(hwkey_session, HWKEY_OPAQUE_KEY_ID, key_handle,
&key_handle_size);
EXPECT_EQ(NO_ERROR, rc, "Could not get opaque key handle");
EXPECT_LE(key_handle_size, HWKEY_OPAQUE_HANDLE_MAX_SIZE,
"Wrong handle size");
_state->args_encrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_encrypt.key.data_ptr = key_handle;
_state->args_encrypt.key.len = key_handle_size;
_state->args_encrypt.key.shm_hd_ptr = NULL;
for (size_t i = 0; i < MAX_TRY_TIMES; i++) {
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
ASSERT_EQ(NO_ERROR, rc, "encryption - in loop");
}
memcpy(_state->shm_base, hwaes_cbc_plaintext, sizeof(hwaes_cbc_plaintext));
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(NO_ERROR, rc, "encryption - final round");
rc = memcmp(_state->shm_base, opaque_key_ciphertext,
sizeof(opaque_key_ciphertext));
EXPECT_EQ(0, rc, "wrong encryption result");
hwkey_close(hwkey_session);
test_abort:;
}
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(InvalidOpaqueKeySize)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE + 1] = {0};
_state->args_encrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_encrypt.key.data_ptr = key_handle;
_state->args_encrypt.key.len = sizeof(key_handle);
_state->args_encrypt.key.shm_hd_ptr = NULL;
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "Did not error on invalid opaque key size");
hwkey_close(hwkey_session);
test_abort:;
}
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(InvalidOpaqueKeyTerminator)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE];
/* Non-null terminated handle */
memset(key_handle, 0xa, HWKEY_OPAQUE_HANDLE_MAX_SIZE);
_state->args_encrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_encrypt.key.data_ptr = key_handle;
_state->args_encrypt.key.len = sizeof(key_handle);
_state->args_encrypt.key.shm_hd_ptr = NULL;
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_INVALID_ARGS, rc, "Did not error on invalid opaque key");
hwkey_close(hwkey_session);
test_abort:;
}
TEST_F(hwaes, DISABLED_WITHOUT_HWCRYPTO_UNITTEST(OutdatedOpaqueHandle)) {
long rc = hwkey_open();
ASSERT_GE(rc, 0, "Could not connect to hwkey");
hwkey_session_t hwkey_session = (hwkey_session_t)rc;
uint8_t key_handle[HWKEY_OPAQUE_HANDLE_MAX_SIZE] = {0};
uint32_t key_handle_size = HWKEY_OPAQUE_HANDLE_MAX_SIZE;
rc = hwkey_get_keyslot_data(hwkey_session, HWKEY_OPAQUE_KEY_ID, key_handle,
&key_handle_size);
EXPECT_EQ(NO_ERROR, rc, "Could not get opaque key handle");
EXPECT_LE(key_handle_size, HWKEY_OPAQUE_HANDLE_MAX_SIZE,
"Wrong handle size");
/* Close the session and invalidate the handle */
hwkey_close(hwkey_session);
_state->args_encrypt.key_type = HWAES_OPAQUE_HANDLE;
_state->args_encrypt.key.data_ptr = key_handle;
_state->args_encrypt.key.len = key_handle_size;
_state->args_encrypt.key.shm_hd_ptr = NULL;
rc = hwaes_encrypt(_state->hwaes_session, &_state->args_encrypt);
EXPECT_EQ(ERR_IO, rc, "Should not be able to fetch key for opaque handle");
test_abort:;
}
PORT_TEST(hwaes, "com.android.trusty.hwaes.test")