/*
* 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[] = {0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test1_iv[] = {0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test1_plaintext[] = {
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test1_ciphertext[] = {
0 x03, 0 x88, 0 xda, 0 xce, 0 x60, 0 xb6, 0 xa3, 0 x92,
0 xf3, 0 x28, 0 xc2, 0 xb9, 0 x71, 0 xb2, 0 xfe, 0 x78};
static const uint8_t gcm_test1_aad[] = {};
static const uint8_t gcm_test1_tag[] = {0 xab, 0 x6e, 0 x47, 0 xd4, 0 x2c, 0 xec,
0 x13, 0 xbd, 0 xf5, 0 x3a, 0 x67, 0 xb2,
0 x12, 0 x57, 0 xbd, 0 xdf};
static const uint8_t gcm_test2_key[] = {0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65,
0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f, 0 x94,
0 x67, 0 x30, 0 x83, 0 x08};
static const uint8_t gcm_test2_iv[] = {0 xca, 0 xfe, 0 xba, 0 xbe, 0 xfa, 0 xce,
0 xdb, 0 xad, 0 xde, 0 xca, 0 xf8, 0 x88};
static const uint8_t gcm_test2_plaintext[] = {
0 xd9, 0 x31, 0 x32, 0 x25, 0 xf8, 0 x84, 0 x06, 0 xe5, 0 xa5, 0 x59, 0 x09,
0 xc5, 0 xaf, 0 xf5, 0 x26, 0 x9a, 0 x86, 0 xa7, 0 xa9, 0 x53, 0 x15, 0 x34,
0 xf7, 0 xda, 0 x2e, 0 x4c, 0 x30, 0 x3d, 0 x8a, 0 x31, 0 x8a, 0 x72, 0 x1c,
0 x3c, 0 x0c, 0 x95, 0 x95, 0 x68, 0 x09, 0 x53, 0 x2f, 0 xcf, 0 x0e, 0 x24,
0 x49, 0 xa6, 0 xb5, 0 x25, 0 xb1, 0 x6a, 0 xed, 0 xf5, 0 xaa, 0 x0d, 0 xe6,
0 x57, 0 xba, 0 x63, 0 x7b, 0 x39, 0 x1a, 0 xaf, 0 xd2, 0 x55};
static const uint8_t gcm_test2_ciphertext[] = {
0 x42, 0 x83, 0 x1e, 0 xc2, 0 x21, 0 x77, 0 x74, 0 x24, 0 x4b, 0 x72, 0 x21,
0 xb7, 0 x84, 0 xd0, 0 xd4, 0 x9c, 0 xe3, 0 xaa, 0 x21, 0 x2f, 0 x2c, 0 x02,
0 xa4, 0 xe0, 0 x35, 0 xc1, 0 x7e, 0 x23, 0 x29, 0 xac, 0 xa1, 0 x2e, 0 x21,
0 xd5, 0 x14, 0 xb2, 0 x54, 0 x66, 0 x93, 0 x1c, 0 x7d, 0 x8f, 0 x6a, 0 x5a,
0 xac, 0 x84, 0 xaa, 0 x05, 0 x1b, 0 xa3, 0 x0b, 0 x39, 0 x6a, 0 x0a, 0 xac,
0 x97, 0 x3d, 0 x58, 0 xe0, 0 x91, 0 x47, 0 x3f, 0 x59, 0 x85};
static const uint8_t gcm_test2_aad[] = {};
static const uint8_t gcm_test2_tag[] = {0 x4d, 0 x5c, 0 x2a, 0 xf3, 0 x27, 0 xcd,
0 x64, 0 xa6, 0 x2c, 0 xf3, 0 x5a, 0 xbd,
0 x2b, 0 xa6, 0 xfa, 0 xb4};
static const uint8_t gcm_test3_key[] = {0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65,
0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f, 0 x94,
0 x67, 0 x30, 0 x83, 0 x08};
static const uint8_t gcm_test3_iv[] = {0 xca, 0 xfe, 0 xba, 0 xbe, 0 xfa, 0 xce,
0 xdb, 0 xad, 0 xde, 0 xca, 0 xf8, 0 x88};
static const uint8_t gcm_test3_plaintext[] = {
0 xd9, 0 x31, 0 x32, 0 x25, 0 xf8, 0 x84, 0 x06, 0 xe5, 0 xa5, 0 x59, 0 x09, 0 xc5,
0 xaf, 0 xf5, 0 x26, 0 x9a, 0 x86, 0 xa7, 0 xa9, 0 x53, 0 x15, 0 x34, 0 xf7, 0 xda,
0 x2e, 0 x4c, 0 x30, 0 x3d, 0 x8a, 0 x31, 0 x8a, 0 x72, 0 x1c, 0 x3c, 0 x0c, 0 x95,
0 x95, 0 x68, 0 x09, 0 x53, 0 x2f, 0 xcf, 0 x0e, 0 x24, 0 x49, 0 xa6, 0 xb5, 0 x25,
0 xb1, 0 x6a, 0 xed, 0 xf5, 0 xaa, 0 x0d, 0 xe6, 0 x57, 0 xba, 0 x63, 0 x7b, 0 x39};
static const uint8_t gcm_test3_ciphertext[] = {
0 x42, 0 x83, 0 x1e, 0 xc2, 0 x21, 0 x77, 0 x74, 0 x24, 0 x4b, 0 x72, 0 x21, 0 xb7,
0 x84, 0 xd0, 0 xd4, 0 x9c, 0 xe3, 0 xaa, 0 x21, 0 x2f, 0 x2c, 0 x02, 0 xa4, 0 xe0,
0 x35, 0 xc1, 0 x7e, 0 x23, 0 x29, 0 xac, 0 xa1, 0 x2e, 0 x21, 0 xd5, 0 x14, 0 xb2,
0 x54, 0 x66, 0 x93, 0 x1c, 0 x7d, 0 x8f, 0 x6a, 0 x5a, 0 xac, 0 x84, 0 xaa, 0 x05,
0 x1b, 0 xa3, 0 x0b, 0 x39, 0 x6a, 0 x0a, 0 xac, 0 x97, 0 x3d, 0 x58, 0 xe0, 0 x91};
static const uint8_t gcm_test3_aad[] = {
0 xfe, 0 xed, 0 xfa, 0 xce, 0 xde, 0 xad, 0 xbe, 0 xef, 0 xfe, 0 xed,
0 xfa, 0 xce, 0 xde, 0 xad, 0 xbe, 0 xef, 0 xab, 0 xad, 0 xda, 0 xd2};
static const uint8_t gcm_test3_tag[] = {0 x5b, 0 xc9, 0 x4f, 0 xbc, 0 x32, 0 x21,
0 xa5, 0 xdb, 0 x94, 0 xfa, 0 xe9, 0 x5a,
0 xe7, 0 x12, 0 x1a, 0 x47};
/* AES 256 GCM */
static const uint8_t gcm_test4_key[] = {
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test4_iv[] = {0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test4_plaintext[] = {
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t gcm_test4_ciphertext[] = {
0 xce, 0 xa7, 0 x40, 0 x3d, 0 x4d, 0 x60, 0 x6b, 0 x6e,
0 x07, 0 x4e, 0 xc5, 0 xd3, 0 xba, 0 xf3, 0 x9d, 0 x18};
static const uint8_t gcm_test4_aad[] = {};
static const uint8_t gcm_test4_tag[] = {0 xd0, 0 xd1, 0 xc8, 0 xa7, 0 x99, 0 x99,
0 x6b, 0 xf0, 0 x26, 0 x5b, 0 x98, 0 xb5,
0 xd4, 0 x8a, 0 xb9, 0 x19};
static const uint8_t gcm_test5_key[] = {
0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65, 0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f,
0 x94, 0 x67, 0 x30, 0 x83, 0 x08, 0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65,
0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f, 0 x94, 0 x67, 0 x30, 0 x83, 0 x08};
static const uint8_t gcm_test5_iv[] = {0 xca, 0 xfe, 0 xba, 0 xbe, 0 xfa, 0 xce,
0 xdb, 0 xad, 0 xde, 0 xca, 0 xf8, 0 x88};
static const uint8_t gcm_test5_plaintext[] = {
0 xd9, 0 x31, 0 x32, 0 x25, 0 xf8, 0 x84, 0 x06, 0 xe5, 0 xa5, 0 x59, 0 x09,
0 xc5, 0 xaf, 0 xf5, 0 x26, 0 x9a, 0 x86, 0 xa7, 0 xa9, 0 x53, 0 x15, 0 x34,
0 xf7, 0 xda, 0 x2e, 0 x4c, 0 x30, 0 x3d, 0 x8a, 0 x31, 0 x8a, 0 x72, 0 x1c,
0 x3c, 0 x0c, 0 x95, 0 x95, 0 x68, 0 x09, 0 x53, 0 x2f, 0 xcf, 0 x0e, 0 x24,
0 x49, 0 xa6, 0 xb5, 0 x25, 0 xb1, 0 x6a, 0 xed, 0 xf5, 0 xaa, 0 x0d, 0 xe6,
0 x57, 0 xba, 0 x63, 0 x7b, 0 x39, 0 x1a, 0 xaf, 0 xd2, 0 x55};
static const uint8_t gcm_test5_ciphertext[] = {
0 x52, 0 x2d, 0 xc1, 0 xf0, 0 x99, 0 x56, 0 x7d, 0 x07, 0 xf4, 0 x7f, 0 x37,
0 xa3, 0 x2a, 0 x84, 0 x42, 0 x7d, 0 x64, 0 x3a, 0 x8c, 0 xdc, 0 xbf, 0 xe5,
0 xc0, 0 xc9, 0 x75, 0 x98, 0 xa2, 0 xbd, 0 x25, 0 x55, 0 xd1, 0 xaa, 0 x8c,
0 xb0, 0 x8e, 0 x48, 0 x59, 0 x0d, 0 xbb, 0 x3d, 0 xa7, 0 xb0, 0 x8b, 0 x10,
0 x56, 0 x82, 0 x88, 0 x38, 0 xc5, 0 xf6, 0 x1e, 0 x63, 0 x93, 0 xba, 0 x7a,
0 x0a, 0 xbc, 0 xc9, 0 xf6, 0 x62, 0 x89, 0 x80, 0 x15, 0 xad};
static const uint8_t gcm_test5_aad[] = {};
static const uint8_t gcm_test5_tag[] = {0 xb0, 0 x94, 0 xda, 0 xc5, 0 xd9, 0 x34,
0 x71, 0 xbd, 0 xec, 0 x1a, 0 x50, 0 x22,
0 x70, 0 xe3, 0 xcc, 0 x6c};
static const uint8_t gcm_test6_key[] = {
0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65, 0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f,
0 x94, 0 x67, 0 x30, 0 x83, 0 x08, 0 xfe, 0 xff, 0 xe9, 0 x92, 0 x86, 0 x65,
0 x73, 0 x1c, 0 x6d, 0 x6a, 0 x8f, 0 x94, 0 x67, 0 x30, 0 x83, 0 x08};
static const uint8_t gcm_test6_iv[] = {0 xca, 0 xfe, 0 xba, 0 xbe, 0 xfa, 0 xce,
0 xdb, 0 xad, 0 xde, 0 xca, 0 xf8, 0 x88};
static const uint8_t gcm_test6_plaintext[] = {
0 xd9, 0 x31, 0 x32, 0 x25, 0 xf8, 0 x84, 0 x06, 0 xe5, 0 xa5, 0 x59, 0 x09, 0 xc5,
0 xaf, 0 xf5, 0 x26, 0 x9a, 0 x86, 0 xa7, 0 xa9, 0 x53, 0 x15, 0 x34, 0 xf7, 0 xda,
0 x2e, 0 x4c, 0 x30, 0 x3d, 0 x8a, 0 x31, 0 x8a, 0 x72, 0 x1c, 0 x3c, 0 x0c, 0 x95,
0 x95, 0 x68, 0 x09, 0 x53, 0 x2f, 0 xcf, 0 x0e, 0 x24, 0 x49, 0 xa6, 0 xb5, 0 x25,
0 xb1, 0 x6a, 0 xed, 0 xf5, 0 xaa, 0 x0d, 0 xe6, 0 x57, 0 xba, 0 x63, 0 x7b, 0 x39};
static const uint8_t gcm_test6_ciphertext[] = {
0 x52, 0 x2d, 0 xc1, 0 xf0, 0 x99, 0 x56, 0 x7d, 0 x07, 0 xf4, 0 x7f, 0 x37, 0 xa3,
0 x2a, 0 x84, 0 x42, 0 x7d, 0 x64, 0 x3a, 0 x8c, 0 xdc, 0 xbf, 0 xe5, 0 xc0, 0 xc9,
0 x75, 0 x98, 0 xa2, 0 xbd, 0 x25, 0 x55, 0 xd1, 0 xaa, 0 x8c, 0 xb0, 0 x8e, 0 x48,
0 x59, 0 x0d, 0 xbb, 0 x3d, 0 xa7, 0 xb0, 0 x8b, 0 x10, 0 x56, 0 x82, 0 x88, 0 x38,
0 xc5, 0 xf6, 0 x1e, 0 x63, 0 x93, 0 xba, 0 x7a, 0 x0a, 0 xbc, 0 xc9, 0 xf6, 0 x62};
static const uint8_t gcm_test6_aad[] = {
0 xfe, 0 xed, 0 xfa, 0 xce, 0 xde, 0 xad, 0 xbe, 0 xef, 0 xfe, 0 xed,
0 xfa, 0 xce, 0 xde, 0 xad, 0 xbe, 0 xef, 0 xab, 0 xad, 0 xda, 0 xd2};
static const uint8_t gcm_test6_tag[] = {0 x76, 0 xfc, 0 x6e, 0 xce, 0 x0f, 0 x4e,
0 x17, 0 x68, 0 xcd, 0 xdf, 0 x88, 0 x53,
0 xbb, 0 x2d, 0 x55, 0 x1b};
/* 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[] = {
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00,
0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00, 0 x00};
static const uint8_t hwaes_cbc_ciphertext[] = {
0 xdc, 0 x95, 0 xc0, 0 x78, 0 xa2, 0 x40, 0 x89, 0 x89, 0 xad, 0 x48, 0 xa2,
0 x14, 0 x92, 0 x84, 0 x20, 0 x87, 0 x08, 0 xc3, 0 x74, 0 x84, 0 x8c, 0 x22,
0 x82, 0 x33, 0 xc2, 0 xb3, 0 x4f, 0 x33, 0 x2b, 0 xd2, 0 xe9, 0 xd3};
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 = 1 U;
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 = 0 U;
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 = 1 U;
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 = 1 U;
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 = 2 U;
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 = 1 U;
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 + 1 ULL;
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[] = {
0 x8c, 0 xc8, 0 xc0, 0 xc7, 0 x76, 0 x57, 0 xb4, 0 x4f, 0 x22, 0 xd3, 0 x33,
0 x2e, 0 x6f, 0 x23, 0 x92, 0 x51, 0 x21, 0 x69, 0 x30, 0 xff, 0 x84, 0 x88,
0 x4c, 0 x38, 0 x04, 0 xe5, 0 x17, 0 xad, 0 x5c, 0 x08, 0 x87, 0 xfc,
};
#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, 0 xa, 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" )
Messung V0.5 in Prozent C=90 H=89 G=89
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet am 2026-06-26)
¤
*© Formatika GbR, Deutschland