| /* |
| * 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") |