Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  hwaes-test.c

  Sprache: C
 

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

Messung V0.5 in Prozent
C=90 H=89 G=89

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet am  2026-06-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik