/* * Unit tests for validity HAL (device descriptor lookup and flash layout) * * Copyright (C) 2024 libfprint contributors * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. */ #include #include #include "drivers/validity/validity.h" #include "drivers/validity/validity_hal.h" /* ================================================================ * T7.1: HAL lookup by device type — all valid types return non-NULL * ================================================================ */ static void test_hal_lookup_all_types (void) { const guint types[] = { VALIDITY_DEV_90, VALIDITY_DEV_97, VALIDITY_DEV_9A, VALIDITY_DEV_9D }; for (guint i = 0; i < G_N_ELEMENTS (types); i++) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (types[i]); g_assert_nonnull (desc); g_assert_cmpuint (desc->vid, >, 0); g_assert_cmpuint (desc->pid, >, 0); } } /* ================================================================ * T7.2: HAL lookup by PID — all supported VID/PID combos * ================================================================ */ static void test_hal_lookup_by_pid (void) { /* All 4 supported devices */ struct { guint16 vid; guint16 pid; } devices[] = { { 0x138a, 0x0090 }, { 0x138a, 0x0097 }, { 0x06cb, 0x009a }, { 0x138a, 0x009d }, }; for (guint i = 0; i < G_N_ELEMENTS (devices); i++) { const ValidityDeviceDesc *desc = validity_hal_device_lookup_by_pid (devices[i].vid, devices[i].pid); g_assert_nonnull (desc); g_assert_cmpuint (desc->vid, ==, devices[i].vid); g_assert_cmpuint (desc->pid, ==, devices[i].pid); } } /* ================================================================ * T7.3: HAL lookup — invalid type returns NULL * ================================================================ */ static void test_hal_lookup_invalid (void) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (99); g_assert_null (desc); } /* ================================================================ * T7.4: HAL lookup by PID — unknown PID returns NULL * ================================================================ */ static void test_hal_lookup_by_pid_invalid (void) { const ValidityDeviceDesc *desc = validity_hal_device_lookup_by_pid (0x1234, 0x5678); g_assert_null (desc); } /* ================================================================ * T7.5: All devices have non-empty blobs * ================================================================ */ static void test_hal_blobs_present (void) { const guint types[] = { VALIDITY_DEV_90, VALIDITY_DEV_97, VALIDITY_DEV_9A, VALIDITY_DEV_9D }; for (guint i = 0; i < G_N_ELEMENTS (types); i++) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (types[i]); g_assert_nonnull (desc); /* init_hardcoded must be present for all */ g_assert_nonnull (desc->init_hardcoded); g_assert_cmpuint (desc->init_hardcoded_len, >, 0); /* reset_blob must be present for all */ g_assert_nonnull (desc->reset_blob); g_assert_cmpuint (desc->reset_blob_len, >, 0); /* db_write_enable must be present for all */ g_assert_nonnull (desc->db_write_enable); g_assert_cmpuint (desc->db_write_enable_len, >, 0); } } /* ================================================================ * T7.6: PID 0090 has smaller db partition and no clean_slate blob * ================================================================ */ static void test_hal_pid_0090_specifics (void) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (VALIDITY_DEV_90); g_assert_nonnull (desc); /* 0090 has no init_hardcoded_clean_slate */ g_assert_null (desc->init_clean_slate); g_assert_cmpuint (desc->init_clean_slate_len, ==, 0); /* Flash layout should exist */ g_assert_nonnull (desc->flash_layout); g_assert_cmpuint (desc->flash_layout->num_partitions, ==, VALIDITY_FLASH_NUM_PARTITIONS); } /* ================================================================ * T7.7: Non-0090 devices have init_hardcoded_clean_slate * ================================================================ */ static void test_hal_clean_slate_present (void) { const guint types[] = { VALIDITY_DEV_97, VALIDITY_DEV_9A, VALIDITY_DEV_9D }; for (guint i = 0; i < G_N_ELEMENTS (types); i++) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (types[i]); g_assert_nonnull (desc); g_assert_nonnull (desc->init_clean_slate); g_assert_cmpuint (desc->init_clean_slate_len, >, 0); } } /* ================================================================ * T7.8: Flash layout has valid partition table * ================================================================ */ static void test_hal_flash_layout (void) { const guint types[] = { VALIDITY_DEV_90, VALIDITY_DEV_97, VALIDITY_DEV_9A, VALIDITY_DEV_9D }; for (guint i = 0; i < G_N_ELEMENTS (types); i++) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (types[i]); g_assert_nonnull (desc); g_assert_nonnull (desc->flash_layout); const ValidityFlashLayout *layout = desc->flash_layout; g_assert_cmpuint (layout->num_partitions, ==, VALIDITY_FLASH_NUM_PARTITIONS); /* Signature must be 256 bytes */ g_assert_nonnull (layout->partition_sig); g_assert_cmpuint (layout->partition_sig_len, ==, VALIDITY_PARTITION_SIG_SIZE); /* Verify partitions are ordered and non-overlapping */ for (guint p = 0; p < layout->num_partitions; p++) { const ValidityPartition *part = &layout->partitions[p]; g_assert_cmpuint (part->size, >, 0); if (p > 0) { const ValidityPartition *prev = &layout->partitions[p - 1]; g_assert_cmpuint (part->offset, >=, prev->offset + prev->size); } } } } /* ================================================================ * T7.9: Blob sizes match expected values from python-validity * ================================================================ */ static void test_hal_blob_sizes (void) { const ValidityDeviceDesc *desc_9a = validity_hal_device_lookup (VALIDITY_DEV_9A); g_assert_nonnull (desc_9a); /* 009a blobs: init=581, clean_slate=741, reset=12037, dbe=3621 */ g_assert_cmpuint (desc_9a->init_hardcoded_len, ==, 581); g_assert_cmpuint (desc_9a->init_clean_slate_len, ==, 741); g_assert_cmpuint (desc_9a->reset_blob_len, ==, 12037); g_assert_cmpuint (desc_9a->db_write_enable_len, ==, 3621); const ValidityDeviceDesc *desc_90 = validity_hal_device_lookup (VALIDITY_DEV_90); g_assert_nonnull (desc_90); /* 0090 blobs: init=485, no clean_slate, reset=11493, dbe=1765 */ g_assert_cmpuint (desc_90->init_hardcoded_len, ==, 485); g_assert_cmpuint (desc_90->reset_blob_len, ==, 11493); g_assert_cmpuint (desc_90->db_write_enable_len, ==, 1765); } /* ================================================================ * T7.10: Lookup consistency — by-type and by-PID return same pointer * ================================================================ */ static void test_hal_lookup_consistency (void) { const ValidityDeviceDesc *by_type = validity_hal_device_lookup (VALIDITY_DEV_9A); const ValidityDeviceDesc *by_pid = validity_hal_device_lookup_by_pid (0x06cb, 0x009a); g_assert_true (by_type == by_pid); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/validity/hal/lookup-all-types", test_hal_lookup_all_types); g_test_add_func ("/validity/hal/lookup-by-pid", test_hal_lookup_by_pid); g_test_add_func ("/validity/hal/lookup-invalid", test_hal_lookup_invalid); g_test_add_func ("/validity/hal/lookup-by-pid-invalid", test_hal_lookup_by_pid_invalid); g_test_add_func ("/validity/hal/blobs-present", test_hal_blobs_present); g_test_add_func ("/validity/hal/pid-0090-specifics", test_hal_pid_0090_specifics); g_test_add_func ("/validity/hal/clean-slate-present", test_hal_clean_slate_present); g_test_add_func ("/validity/hal/flash-layout", test_hal_flash_layout); g_test_add_func ("/validity/hal/blob-sizes", test_hal_blob_sizes); g_test_add_func ("/validity/hal/lookup-consistency", test_hal_lookup_consistency); return g_test_run (); }