diff --git a/libfprint/drivers/validity/validity.c b/libfprint/drivers/validity/validity.c index 592b768a..fc549c81 100644 --- a/libfprint/drivers/validity/validity.c +++ b/libfprint/drivers/validity/validity.c @@ -289,8 +289,8 @@ fwext_upload_ssm_done (FpiSsm *ssm, * that tells fprintd to retry. */ fp_info ("Firmware extension uploaded successfully — device rebooting"); fpi_ssm_mark_failed (self->open_ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_REMOVED, - "Device rebooting after firmware upload")); + fpi_device_error_new_msg (FP_DEVICE_ERROR_REMOVED, + "Device rebooting after firmware upload")); } /* Callback for pairing child SSM */ @@ -332,8 +332,8 @@ pair_ssm_done (FpiSsm *ssm, fp_info ("Pairing complete — device rebooting, signalling removal"); validity_pair_state_free (&self->pair_state); fpi_ssm_mark_failed (self->open_ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_REMOVED, - "Device rebooting after pairing")); + fpi_device_error_new_msg (FP_DEVICE_ERROR_REMOVED, + "Device rebooting after pairing")); return; } @@ -626,8 +626,8 @@ open_run_state (FpiSsm *ssm, * TLS works independently of fwext (partition 2). */ self->open_ssm = ssm; FpiSsm *flash_ssm = fpi_ssm_new (dev, - validity_tls_flash_read_run_state, - TLS_FLASH_READ_NUM_STATES); + validity_tls_flash_read_run_state, + TLS_FLASH_READ_NUM_STATES); fpi_ssm_start (flash_ssm, flash_read_ssm_done); } break; @@ -692,8 +692,8 @@ open_run_state (FpiSsm *ssm, self->open_ssm = ssm; FpiSsm *tls_ssm = fpi_ssm_new (dev, - validity_tls_handshake_run_state, - TLS_HS_NUM_STATES); + validity_tls_handshake_run_state, + TLS_HS_NUM_STATES); fpi_ssm_start (tls_ssm, tls_handshake_ssm_done); } break; @@ -766,13 +766,17 @@ open_run_state (FpiSsm *ssm, self->sensor.device_info->type); if (self->sensor.type_info) - fp_info ("Sensor type: 0x%04x, %u bytes/line, %ux repeat", - self->sensor.type_info->sensor_type, - self->sensor.type_info->bytes_per_line, - self->sensor.type_info->repeat_multiplier); + { + fp_info ("Sensor type: 0x%04x, %u bytes/line, %ux repeat", + self->sensor.type_info->sensor_type, + self->sensor.type_info->bytes_per_line, + self->sensor.type_info->repeat_multiplier); + } else - fp_warn ("Unknown sensor type 0x%04x", - self->sensor.device_info->type); + { + fp_warn ("Unknown sensor type 0x%04x", + self->sensor.device_info->type); + } } else { @@ -939,9 +943,9 @@ open_run_state (FpiSsm *ssm, /* Read calibration data from EP 0x82. * PY: usb.read_82() — reads all bulk data from the sensor. */ { - gsize expected_size = (gsize)(self->capture.calibration_frames * - self->capture.lines_per_frame + 1) * - self->capture.bytes_per_line; + gsize expected_size = (gsize) (self->capture.calibration_frames * + self->capture.lines_per_frame + 1) * + self->capture.bytes_per_line; FpiUsbTransfer *xfer = fpi_usb_transfer_new (dev); fp_dbg ("Reading calibration data: %zu bytes from EP 0x82", @@ -1015,7 +1019,9 @@ open_run_state (FpiSsm *ssm, self->calib_iteration++; if (self->calib_iteration < self->capture.calibration_iterations) - fpi_ssm_jump_to_state (ssm, OPEN_CALIBRATE_SEND); + { + fpi_ssm_jump_to_state (ssm, OPEN_CALIBRATE_SEND); + } else { fp_info ("Sensor calibration complete"); diff --git a/libfprint/drivers/validity/validity.h b/libfprint/drivers/validity/validity.h index eecca284..acbc12e9 100644 --- a/libfprint/drivers/validity/validity.h +++ b/libfprint/drivers/validity/validity.h @@ -29,23 +29,23 @@ #include "validity_tls.h" /* USB Endpoint addresses */ -#define VALIDITY_EP_CMD_OUT 0x01 -#define VALIDITY_EP_CMD_IN 0x81 -#define VALIDITY_EP_DATA_IN 0x82 -#define VALIDITY_EP_INT_IN 0x83 +#define VALIDITY_EP_CMD_OUT 0x01 +#define VALIDITY_EP_CMD_IN 0x81 +#define VALIDITY_EP_DATA_IN 0x82 +#define VALIDITY_EP_INT_IN 0x83 /* USB transfer parameters */ -#define VALIDITY_USB_TIMEOUT 15000 -#define VALIDITY_USB_INT_TIMEOUT 100 -#define VALIDITY_MAX_TRANSFER_LEN (100 * 1024) +#define VALIDITY_USB_TIMEOUT 15000 +#define VALIDITY_USB_INT_TIMEOUT 100 +#define VALIDITY_MAX_TRANSFER_LEN (100 * 1024) #define VALIDITY_USB_INT_DATA_SIZE 1024 #define VALIDITY_USB_SEND_HEADER_LEN 1 /* Number of enroll stages */ -#define VALIDITY_ENROLL_STAGES 8 +#define VALIDITY_ENROLL_STAGES 8 /* Interrupt response bits */ -#define VALIDITY_INT_FINGER_DOWN 0x02 +#define VALIDITY_INT_FINGER_DOWN 0x02 #define VALIDITY_INT_SCAN_COMPLETE 0x04 typedef enum { @@ -243,14 +243,14 @@ G_DECLARE_FINAL_TYPE (FpiDeviceValidity, fpi_device_validity, struct _FpiDeviceValidity { - FpDevice parent; + FpDevice parent; - ValidityDeviceType dev_type; + ValidityDeviceType dev_type; ValidityVersionInfo version_info; - GCancellable *interrupt_cancellable; + GCancellable *interrupt_cancellable; /* TLS session state */ - ValidityTlsState tls; + ValidityTlsState tls; /* Sensor identification and HAL state (post-TLS) */ ValiditySensorState sensor; @@ -259,50 +259,50 @@ struct _FpiDeviceValidity ValidityCaptureState capture; /* Firmware extension status */ - gboolean fwext_loaded; + gboolean fwext_loaded; /* Pairing state (for uninitialized devices) */ - ValidityPairState pair_state; + ValidityPairState pair_state; /* Calibration state */ - gboolean calibrated; - guint calib_iteration; + gboolean calibrated; + guint calib_iteration; /* Enrollment state */ - guint32 enroll_key; - guint8 *enroll_template; - gsize enroll_template_len; - guint enroll_stage; - guint16 enroll_user_dbid; - guint16 enroll_storage_dbid; - guint scan_incomplete_count; + guint32 enroll_key; + guint8 *enroll_template; + gsize enroll_template_len; + guint enroll_stage; + guint16 enroll_user_dbid; + guint16 enroll_storage_dbid; + guint scan_incomplete_count; /* Verify/identify mode flag: TRUE = identify, FALSE = verify */ - gboolean identify_mode; + gboolean identify_mode; /* List prints state */ ValidityUserStorage list_storage; - guint list_user_idx; + guint list_user_idx; /* Delete state */ - guint16 delete_storage_dbid; - guint16 delete_finger_subtype; - guint16 delete_finger_dbid; + guint16 delete_storage_dbid; + guint16 delete_finger_subtype; + guint16 delete_finger_dbid; /* Command SSM: manages the send-cmd/recv-response cycle */ - FpiSsm *cmd_ssm; + FpiSsm *cmd_ssm; /* Parent SSM: back-pointer for non-subsm child SSMs */ - FpiSsm *open_ssm; + FpiSsm *open_ssm; /* Pending response data stashed for higher-level SSM consumption */ - guint16 cmd_response_status; - guint8 *cmd_response_data; - gsize cmd_response_len; + guint16 cmd_response_status; + guint8 *cmd_response_data; + gsize cmd_response_len; /* Bulk data buffer (EP 0x82 reads during capture/calibration) */ - guint8 *bulk_data; - gsize bulk_data_len; + guint8 *bulk_data; + gsize bulk_data_len; }; /* Enrollment SSM (validity_enroll.c) */ @@ -322,9 +322,9 @@ typedef struct } EnrollmentUpdateResult; void enrollment_update_result_clear (EnrollmentUpdateResult *r); -gboolean parse_enrollment_update_response (const guint8 *data, - gsize data_len, - EnrollmentUpdateResult *result); +gboolean parse_enrollment_update_response (const guint8 *data, + gsize data_len, + EnrollmentUpdateResult *result); /* Verify/Identify SSMs (validity_verify.c) */ void validity_verify (FpDevice *device); diff --git a/libfprint/drivers/validity/validity_capture.c b/libfprint/drivers/validity/validity_capture.c index 3b0fcc2e..c87630c1 100644 --- a/libfprint/drivers/validity/validity_capture.c +++ b/libfprint/drivers/validity/validity_capture.c @@ -41,7 +41,7 @@ validity_capture_split_chunks (const guint8 *data, gsize *n_chunks) { GArray *arr; - gsize offset = 0; + gsize offset = 0; g_return_val_if_fail (data != NULL || data_len == 0, NULL); g_return_val_if_fail (n_chunks != NULL, NULL); @@ -81,9 +81,9 @@ validity_capture_merge_chunks (const ValidityCaptureChunk *chunks, gsize n_chunks, gsize *out_len) { - gsize total = 0; + gsize total = 0; guint8 *buf; - gsize offset = 0; + gsize offset = 0; g_return_val_if_fail (out_len != NULL, NULL); @@ -192,7 +192,7 @@ validity_capture_decode_insn (const guint8 *data, return FALSE; *opcode = TST_OP_ENABLE_SO; *insn_len = 2; - operands[0] = ((guint32)(b0 & 1) << 8) | data[1]; + operands[0] = ((guint32) (b0 & 1) << 8) | data[1]; *n_operands = 1; return TRUE; } @@ -204,7 +204,7 @@ validity_capture_decode_insn (const guint8 *data, return FALSE; *opcode = TST_OP_DISABLE_SO; *insn_len = 2; - operands[0] = ((guint32)(b0 & 1) << 8) | data[1]; + operands[0] = ((guint32) (b0 & 1) << 8) | data[1]; *n_operands = 1; return TRUE; } @@ -250,7 +250,7 @@ validity_capture_decode_insn (const guint8 *data, return FALSE; *opcode = TST_OP_REG_WRITE; *insn_len = 3; - operands[0] = (guint32)(b0 & 0x3f) * 4 + 0x80002000; /* register address */ + operands[0] = (guint32) (b0 & 0x3f) * 4 + 0x80002000; /* register address */ operands[1] = (guint32) data[1] | ((guint32) data[2] << 8); /* value */ *n_operands = 2; return TRUE; @@ -294,7 +294,7 @@ validity_capture_find_nth_insn (const guint8 *data, while (pc < data_len) { - guint8 opcode, len, n_ops; + guint8 opcode, len, n_ops; guint32 operands[3]; if (!validity_capture_decode_insn (data + pc, data_len - pc, @@ -324,7 +324,7 @@ validity_capture_find_nth_regwrite (const guint8 *data, while (pc < data_len) { - guint8 opcode, len, n_ops; + guint8 opcode, len, n_ops; guint32 operands[3]; if (!validity_capture_decode_insn (data + pc, data_len - pc, @@ -402,7 +402,7 @@ validity_capture_patch_timeslot_again (guint8 *data, guint16 key_calibration_line) { gssize call_target = -1; - gsize pc = 0; + gsize pc = 0; gssize match = -1; g_return_val_if_fail (data != NULL, FALSE); @@ -411,7 +411,7 @@ validity_capture_patch_timeslot_again (guint8 *data, /* First pass: find the last Call instruction's destination address */ while (pc < data_len) { - guint8 opcode, len, n_ops; + guint8 opcode, len, n_ops; guint32 operands[3]; if (!validity_capture_decode_insn (data + pc, data_len - pc, @@ -438,7 +438,7 @@ validity_capture_patch_timeslot_again (guint8 *data, pc = (gsize) call_target; while (pc < data_len) { - guint8 opcode, len, n_ops; + guint8 opcode, len, n_ops; guint32 operands[3]; if (!validity_capture_decode_insn (data + pc, data_len - pc, @@ -477,9 +477,11 @@ validity_capture_patch_timeslot_again (guint8 *data, static guint8 clip_signed (gint x) { - if (x < -128) x = -128; - if (x > 127) x = 127; - return (guint8)(x & 0xff); + if (x < -128) + x = -128; + if (x > 127) + x = 127; + return (guint8) (x & 0xff); } /* Scale a byte value for calibration processing */ @@ -487,6 +489,7 @@ static guint8 scale_byte (guint8 x) { gint val = (gint) x - 0x80; + val = val * 10 / 0x22; return clip_signed (val); } @@ -497,6 +500,7 @@ add_signed_bytes (guint8 l, guint8 r) { gint8 sl = (gint8) l; gint8 sr = (gint8) r; + return clip_signed ((gint) sl + (gint) sr); } @@ -513,11 +517,11 @@ validity_capture_bitpack (const guint8 *values, guint8 *out_v1, gsize *out_len) { - guint8 min_val = 0xff, max_val = 0; - guint8 useful_bits; - guint max_delta; - gsize total_bits; - gsize total_bytes; + guint8 min_val = 0xff, max_val = 0; + guint8 useful_bits; + guint max_delta; + gsize total_bits; + gsize total_bytes; guint8 *packed; g_return_val_if_fail (values != NULL && values_len > 0, NULL); @@ -526,8 +530,10 @@ validity_capture_bitpack (const guint8 *values, /* Find min and max */ for (gsize i = 0; i < values_len; i++) { - if (values[i] < min_val) min_val = values[i]; - if (values[i] > max_val) max_val = values[i]; + if (values[i] < min_val) + min_val = values[i]; + if (values[i] > max_val) + max_val = values[i]; } max_delta = max_val - min_val; @@ -610,10 +616,8 @@ get_key_line (const guint8 *calib_data, memcpy (key_line, calib_data + key_offset, line_width); /* Replace value 5 with 4 (python: [i-1 if i == 5 else i for i in key_line]) */ for (guint16 i = 0; i < line_width; i++) - { - if (key_line[i] == 5) - key_line[i] = 4; - } + if (key_line[i] == 5) + key_line[i] = 4; } } @@ -633,13 +637,13 @@ get_key_line (const guint8 *calib_data, /* Internal line entry for building Line Update chunks */ typedef struct { - guint32 mask; - guint32 flags; - guint8 *data; - gsize data_len; - guint8 v0; /* bitpack: useful bits */ - guint8 v1; /* bitpack: minimum */ - guint16 v2; /* unused in type 1, always 0 */ + guint32 mask; + guint32 flags; + guint8 *data; + gsize data_len; + guint8 v0; /* bitpack: useful bits */ + guint8 v1; /* bitpack: minimum */ + guint16 v2; /* unused in type 1, always 0 */ } LineEntry; /* @@ -654,22 +658,22 @@ typedef struct * n_chunks is updated with the new count. */ static ValidityCaptureChunk * -build_line_update_type1 (const ValidityCaptureState *capture, - const ValiditySensorTypeInfo *type_info, - ValidityCaptureMode mode, - ValidityCaptureChunk *in_chunks, - gsize in_n_chunks, - gsize *out_n_chunks) +build_line_update_type1 (const ValidityCaptureState *capture, + const ValiditySensorTypeInfo *type_info, + ValidityCaptureMode mode, + ValidityCaptureChunk *in_chunks, + gsize in_n_chunks, + gsize *out_n_chunks) { GArray *chunks_arr; GArray *lines_arr; - gsize cnt = 2; /* line counter starts at 2 per python-validity */ + gsize cnt = 2; /* line counter starts at 2 per python-validity */ /* Save the patched TST (before key_line replacement) for instruction * searches later. PY searches the original patched tst variable, not * the chunk data that has the key_line prepended. */ g_autofree guint8 *patched_tst = NULL; - gsize patched_tst_len = 0; + gsize patched_tst_len = 0; /* Copy input chunks, patching timeslot table in-place */ chunks_arr = g_array_new (FALSE, TRUE, sizeof (ValidityCaptureChunk)); @@ -685,12 +689,14 @@ build_line_update_type1 (const ValidityCaptureState *capture, if (c.type == CAPT_CHUNK_TIMESLOT_2D && c.data && c.size > 0) { validity_capture_patch_timeslot_table (c.data, c.size, TRUE, - type_info->repeat_multiplier); + type_info->repeat_multiplier); if (mode != VALIDITY_CAPTURE_CALIBRATE) - validity_capture_patch_timeslot_again (c.data, c.size, - capture->factory_calibration_values, - capture->factory_calibration_values_len, - capture->key_calibration_line); + { + validity_capture_patch_timeslot_again (c.data, c.size, + capture->factory_calibration_values, + capture->factory_calibration_values_len, + capture->key_calibration_line); + } /* Save the patched TST before key_line replacement. * Instruction searches must use this, not the key_line-modified data. */ @@ -846,88 +852,90 @@ build_line_update_type1 (const ValidityCaptureState *capture, lines_arr = g_array_new (FALSE, TRUE, sizeof (LineEntry)); /* We need the patched timeslot table (before key_line replacement) - * for instruction searches — see PY's line_update_type_1 which uses - * the 'tst' variable, not 'c[1]' (which has key_line prepended). */ + * for instruction searches — see PY's line_update_type_1 which uses + * the 'tst' variable, not 'c[1]' (which has key_line prepended). */ if (patched_tst && patched_tst_len > 0) { const guint8 *tst_data = patched_tst; - gsize tst_len = patched_tst_len; - /* Line 0: calibration blob at Enable Rx position */ - { - gssize pc = validity_capture_find_nth_insn (tst_data, tst_len, - TST_OP_ENABLE_RX, 2); - if (pc >= 0 && type_info->calibration_blob) - { - LineEntry le = { 0 }; - le.mask = 0xff; - le.flags = ((guint32)(pc + 1)) | ((guint32) cnt << 0x14) | 0x7000000; - le.data = g_memdup2 (type_info->calibration_blob, - type_info->calibration_blob_len); - le.data_len = type_info->calibration_blob_len; - le.v0 = 0x0f; - g_array_append_val (lines_arr, le); - cnt++; - } - } - - /* Line 1: factory calibration values at Register Write position */ - { - gssize pc = validity_capture_find_nth_regwrite (tst_data, tst_len, - 0x8000203C, 1); - if (pc >= 0 && capture->factory_calibration_values) - { - LineEntry le = { 0 }; - le.mask = 0xff; - le.flags = ((guint32)(pc + 1)) | ((guint32) cnt << 0x14) | 0x7000000; - - /* Bitpack the factory calibration values */ - le.data = validity_capture_bitpack ( - capture->factory_calibration_values, - capture->factory_calibration_values_len, - &le.v0, &le.v1, &le.data_len); - le.v0 = (le.v0 - 1) | 8; - cnt++; - - g_array_append_val (lines_arr, le); - } - } - - /* Calibration data lines (if we have calib_data) */ - if (capture->calib_data && capture->calib_data_len > 0) + gsize tst_len = patched_tst_len; + /* Line 0: calibration blob at Enable Rx position */ + { + gssize pc = validity_capture_find_nth_insn (tst_data, tst_len, + TST_OP_ENABLE_RX, 2); + if (pc >= 0 && type_info->calibration_blob) { - gsize bytes_per_cal_line = capture->calib_data_len / - type_info->lines_per_calibration_data; - - for (guint i = 0; i < 112; i += 4) - { - LineEntry le = { 0 }; - le.mask = 0xffffffff; - le.flags = i | (0x85u << 24); - - /* Collect data from each calibration line at offset i */ - gsize row_data_len = 0; - GByteArray *row = g_byte_array_new (); - - for (guint j = 0; j < 112; j++) - { - gsize p = 8 + (gsize) j * bytes_per_cal_line + i; - if (p + 4 <= capture->calib_data_len) - g_byte_array_append (row, capture->calib_data + p, 4); - else - { - guint8 zeros[4] = { 0 }; - g_byte_array_append (row, zeros, 4); - } - } - - le.data_len = row->len; - le.data = g_byte_array_free (row, FALSE); - row_data_len = le.data_len; - - (void) row_data_len; - g_array_append_val (lines_arr, le); - } + LineEntry le = { 0 }; + le.mask = 0xff; + le.flags = ((guint32) (pc + 1)) | ((guint32) cnt << 0x14) | 0x7000000; + le.data = g_memdup2 (type_info->calibration_blob, + type_info->calibration_blob_len); + le.data_len = type_info->calibration_blob_len; + le.v0 = 0x0f; + g_array_append_val (lines_arr, le); + cnt++; } + } + + /* Line 1: factory calibration values at Register Write position */ + { + gssize pc = validity_capture_find_nth_regwrite (tst_data, tst_len, + 0x8000203C, 1); + if (pc >= 0 && capture->factory_calibration_values) + { + LineEntry le = { 0 }; + le.mask = 0xff; + le.flags = ((guint32) (pc + 1)) | ((guint32) cnt << 0x14) | 0x7000000; + + /* Bitpack the factory calibration values */ + le.data = validity_capture_bitpack ( + capture->factory_calibration_values, + capture->factory_calibration_values_len, + &le.v0, &le.v1, &le.data_len); + le.v0 = (le.v0 - 1) | 8; + cnt++; + + g_array_append_val (lines_arr, le); + } + } + + /* Calibration data lines (if we have calib_data) */ + if (capture->calib_data && capture->calib_data_len > 0) + { + gsize bytes_per_cal_line = capture->calib_data_len / + type_info->lines_per_calibration_data; + + for (guint i = 0; i < 112; i += 4) + { + LineEntry le = { 0 }; + le.mask = 0xffffffff; + le.flags = i | (0x85u << 24); + + /* Collect data from each calibration line at offset i */ + gsize row_data_len = 0; + GByteArray *row = g_byte_array_new (); + + for (guint j = 0; j < 112; j++) + { + gsize p = 8 + (gsize) j * bytes_per_cal_line + i; + if (p + 4 <= capture->calib_data_len) + { + g_byte_array_append (row, capture->calib_data + p, 4); + } + else + { + guint8 zeros[4] = { 0 }; + g_byte_array_append (row, zeros, 4); + } + } + + le.data_len = row->len; + le.data = g_byte_array_free (row, FALSE); + row_data_len = le.data_len; + + (void) row_data_len; + g_array_append_val (lines_arr, le); + } + } } /* Align all line data to 4-byte boundary */ @@ -1028,19 +1036,19 @@ build_line_update_type1 (const ValidityCaptureState *capture, * ================================================================ */ guint8 * -validity_capture_build_cmd_02 (const ValidityCaptureState *capture, +validity_capture_build_cmd_02 (const ValidityCaptureState *capture, const ValiditySensorTypeInfo *type_info, ValidityCaptureMode mode, gsize *out_len) { ValidityCaptureChunk *chunks = NULL; ValidityCaptureChunk *patched = NULL; - gsize n_chunks = 0; - gsize n_patched = 0; - guint8 *merged = NULL; - gsize merged_len = 0; - guint8 *cmd = NULL; - guint16 req_lines; + gsize n_chunks = 0; + gsize n_patched = 0; + guint8 *merged = NULL; + gsize merged_len = 0; + guint8 *cmd = NULL; + guint16 req_lines; g_return_val_if_fail (capture != NULL, NULL); g_return_val_if_fail (type_info != NULL, NULL); @@ -1060,7 +1068,7 @@ validity_capture_build_cmd_02 (const ValidityCaptureState *capture, if (capture->is_type1_device) { patched = build_line_update_type1 (capture, type_info, mode, - chunks, n_chunks, &n_patched); + chunks, n_chunks, &n_patched); } else { @@ -1089,7 +1097,7 @@ validity_capture_build_cmd_02 (const ValidityCaptureState *capture, /* Calculate requested lines */ if (mode == VALIDITY_CAPTURE_CALIBRATE) - req_lines = (guint16)(capture->calibration_frames * capture->lines_per_frame + 1); + req_lines = (guint16) (capture->calibration_frames * capture->lines_per_frame + 1); else req_lines = 0; @@ -1123,15 +1131,15 @@ validity_capture_build_cmd_02 (const ValidityCaptureState *capture, * ================================================================ */ gboolean -validity_capture_parse_factory_bits (const guint8 *data, - gsize data_len, - guint8 **cal_values, - gsize *cal_values_len, - guint8 **cal_data, - gsize *cal_data_len) +validity_capture_parse_factory_bits (const guint8 *data, + gsize data_len, + guint8 **cal_values, + gsize *cal_values_len, + guint8 **cal_data, + gsize *cal_data_len) { guint32 wtf, entries; - gsize offset; + gsize offset; gboolean found_subtag3 = FALSE; g_return_val_if_fail (data != NULL, FALSE); @@ -1214,12 +1222,12 @@ validity_capture_average_frames (const guint8 *raw_data, guint8 calibration_frames, gsize *out_len) { - gsize frame_size; + gsize frame_size; guint16 interleave_lines; - guint8 input_frames; - gsize base_address = 0; + guint8 input_frames; + gsize base_address = 0; guint8 *result; - gsize result_len; + gsize result_len; g_return_val_if_fail (raw_data != NULL, NULL); g_return_val_if_fail (out_len != NULL, NULL); @@ -1272,7 +1280,7 @@ validity_capture_average_frames (const guint8 *raw_data, sum += frame[idx]; } result[(gsize) line * bytes_per_line + col] = - (guint8)(sum / interleave_lines); + (guint8) (sum / interleave_lines); } } @@ -1297,7 +1305,7 @@ validity_capture_average_frames (const guint8 *raw_data, if (idx < raw_len) sum += raw_data[idx]; } - result[i] = (guint8)(sum / input_frames); + result[i] = (guint8) (sum / input_frames); } *out_len = result_len; @@ -1325,11 +1333,11 @@ validity_capture_average_frames (const guint8 *raw_data, * ================================================================ */ void -validity_capture_process_calibration (guint8 **calib_data, - gsize *calib_data_len, - const guint8 *averaged_frame, - gsize frame_len, - guint16 bytes_per_line) +validity_capture_process_calibration (guint8 **calib_data, + gsize *calib_data_len, + const guint8 *averaged_frame, + gsize frame_len, + guint16 bytes_per_line) { guint8 *frame_scaled; @@ -1363,7 +1371,7 @@ validity_capture_process_calibration (guint8 **calib_data, /* First 8 bytes: keep as-is from previous */ for (gsize col = 8; col < bytes_per_line && off + col < len; col++) (*calib_data)[off + col] = add_signed_bytes ((*calib_data)[off + col], - frame_scaled[off + col]); + frame_scaled[off + col]); } } else @@ -1469,10 +1477,8 @@ validity_capture_verify_clean_slate (const guint8 *data, /* Check zeroes block */ for (int i = 0; i < 32; i++) - { - if (zeroes[i] != 0) - return FALSE; - } + if (zeroes[i] != 0) + return FALSE; /* Verify hash */ if (68 + inner_len > data_len) @@ -1728,10 +1734,10 @@ static const guint16 line_update_type1_devices[] = { }; const guint8 * -validity_capture_prog_lookup (guint8 rom_major, - guint8 rom_minor, - guint16 dev_type, - gsize *out_len) +validity_capture_prog_lookup (guint8 rom_major, + guint8 rom_minor, + guint16 dev_type, + gsize *out_len) { g_return_val_if_fail (out_len != NULL, NULL); @@ -1791,7 +1797,7 @@ validity_capture_state_setup (ValidityCaptureState *state, gsize factory_bits_len) { const guint8 *prog; - gsize prog_len; + gsize prog_len; g_return_val_if_fail (state != NULL, FALSE); g_return_val_if_fail (type_info != NULL, FALSE); @@ -1830,7 +1836,7 @@ validity_capture_state_setup (ValidityCaptureState *state, if (chunks[i].type == CAPT_CHUNK_2D_PARAMS && chunks[i].size >= 4) { guint32 lines_2d = FP_READ_UINT32_LE (chunks[i].data); - state->lines_per_frame = (guint16)(lines_2d * type_info->repeat_multiplier); + state->lines_per_frame = (guint16) (lines_2d * type_info->repeat_multiplier); break; } } diff --git a/libfprint/drivers/validity/validity_capture.h b/libfprint/drivers/validity/validity_capture.h index dc19e506..2204d167 100644 --- a/libfprint/drivers/validity/validity_capture.h +++ b/libfprint/drivers/validity/validity_capture.h @@ -46,9 +46,9 @@ typedef enum { * ================================================================ */ typedef struct { - guint16 type; - guint16 size; - guint8 *data; /* owned; g_free() when done */ + guint16 type; + guint16 size; + guint8 *data; /* owned; g_free() when done */ } ValidityCaptureChunk; /* ================================================================ @@ -61,28 +61,28 @@ typedef struct gsize capture_prog_len; /* Geometry derived from SensorTypeInfo + CaptureProg */ - guint16 lines_per_frame; - guint16 bytes_per_line; + guint16 lines_per_frame; + guint16 bytes_per_line; /* Calibration parameters (derived from sensor geometry) */ - guint16 key_calibration_line; - guint8 calibration_frames; - guint8 calibration_iterations; + guint16 key_calibration_line; + guint8 calibration_frames; + guint8 calibration_iterations; /* Factory calibration values (from factory_bits subtag 3) */ - guint8 *factory_calibration_values; - gsize factory_calibration_values_len; + guint8 *factory_calibration_values; + gsize factory_calibration_values_len; /* Optional factory calibration data (from factory_bits subtag 7) */ - guint8 *factory_calib_data; - gsize factory_calib_data_len; + guint8 *factory_calib_data; + gsize factory_calib_data_len; /* Accumulated calibration data (built during calibration loop) */ - guint8 *calib_data; - gsize calib_data_len; + guint8 *calib_data; + gsize calib_data_len; /* Whether this is a line_update_type_1 device */ - gboolean is_type1_device; + gboolean is_type1_device; } ValidityCaptureState; /* ================================================================ @@ -133,21 +133,21 @@ gboolean validity_capture_decode_insn (const guint8 *data, guint8 *n_operands); /* Timeslot instruction opcodes */ -#define TST_OP_NOOP 0 -#define TST_OP_END_OF_TABLE 1 -#define TST_OP_RETURN 2 -#define TST_OP_CLEAR_SO 3 -#define TST_OP_END_OF_DATA 4 -#define TST_OP_MACRO 5 -#define TST_OP_ENABLE_RX 6 -#define TST_OP_IDLE_RX 7 -#define TST_OP_ENABLE_SO 8 -#define TST_OP_DISABLE_SO 9 -#define TST_OP_INTERRUPT 10 -#define TST_OP_CALL 11 -#define TST_OP_FEATURES 12 -#define TST_OP_REG_WRITE 13 -#define TST_OP_SAMPLE 14 +#define TST_OP_NOOP 0 +#define TST_OP_END_OF_TABLE 1 +#define TST_OP_RETURN 2 +#define TST_OP_CLEAR_SO 3 +#define TST_OP_END_OF_DATA 4 +#define TST_OP_MACRO 5 +#define TST_OP_ENABLE_RX 6 +#define TST_OP_IDLE_RX 7 +#define TST_OP_ENABLE_SO 8 +#define TST_OP_DISABLE_SO 9 +#define TST_OP_INTERRUPT 10 +#define TST_OP_CALL 11 +#define TST_OP_FEATURES 12 +#define TST_OP_REG_WRITE 13 +#define TST_OP_SAMPLE 14 #define TST_OP_SAMPLE_REPEAT 15 /* @@ -178,8 +178,8 @@ gssize validity_capture_find_nth_regwrite (const guint8 *data, * multiply it by mult and optionally increment the address. * Modifies data in-place. Returns TRUE on success. */ -gboolean validity_capture_patch_timeslot_table (guint8 *data, - gsize data_len, +gboolean validity_capture_patch_timeslot_table (guint8 *data, + gsize data_len, gboolean inc_address, guint8 mult); @@ -210,7 +210,7 @@ gboolean validity_capture_patch_timeslot_again (guint8 *data, * Returns a newly-allocated buffer (caller must g_free) or NULL on error. * Sets out_len to the buffer size. */ -guint8 *validity_capture_build_cmd_02 (const ValidityCaptureState *capture, +guint8 *validity_capture_build_cmd_02 (const ValidityCaptureState *capture, const ValiditySensorTypeInfo *type_info, ValidityCaptureMode mode, gsize *out_len); @@ -230,12 +230,12 @@ guint8 *validity_capture_build_cmd_02 (const ValidityCaptureState *capture, * * Returns TRUE if at least subtag 3 was found. */ -gboolean validity_capture_parse_factory_bits (const guint8 *data, - gsize data_len, - guint8 **cal_values, - gsize *cal_values_len, - guint8 **cal_data, - gsize *cal_data_len); +gboolean validity_capture_parse_factory_bits (const guint8 *data, + gsize data_len, + guint8 **cal_values, + gsize *cal_values_len, + guint8 **cal_data, + gsize *cal_data_len); /* ================================================================ * Frame averaging @@ -268,11 +268,11 @@ guint8 *validity_capture_average_frames (const guint8 *raw_data, * If calib_data is NULL, initializes from the frame. * If non-NULL, combines (adds signed values, clips). */ -void validity_capture_process_calibration (guint8 **calib_data, - gsize *calib_data_len, - const guint8 *averaged_frame, - gsize frame_len, - guint16 bytes_per_line); +void validity_capture_process_calibration (guint8 **calib_data, + gsize *calib_data_len, + const guint8 *averaged_frame, + gsize frame_len, + guint16 bytes_per_line); /* * Build the clean slate format for flash persistence. @@ -353,16 +353,16 @@ const guint8 *validity_capture_glow_end_cmd (gsize *out_len); * Returns a pointer to the static blob data and sets out_len. * Returns NULL if no matching entry is found. */ -const guint8 *validity_capture_prog_lookup (guint8 rom_major, - guint8 rom_minor, - guint16 dev_type, - gsize *out_len); +const guint8 *validity_capture_prog_lookup (guint8 rom_major, + guint8 rom_minor, + guint16 dev_type, + gsize *out_len); /* ================================================================ * Capture state lifecycle * ================================================================ */ -void validity_capture_state_init (ValidityCaptureState *state); +void validity_capture_state_init (ValidityCaptureState *state); void validity_capture_state_clear (ValidityCaptureState *state); /* @@ -379,18 +379,18 @@ gboolean validity_capture_state_setup (ValidityCaptureState *state, gsize factory_bits_len); /* Chunk type IDs used in capture programs */ -#define CAPT_CHUNK_REPLY_CONFIG 0x0017 -#define CAPT_CHUNK_FINGER_DETECT 0x0026 -#define CAPT_CHUNK_IMAGE_RECON 0x002e -#define CAPT_CHUNK_2D_PARAMS 0x002f -#define CAPT_CHUNK_LINE_UPDATE 0x0030 -#define CAPT_CHUNK_TIMESLOT_2D 0x0034 -#define CAPT_CHUNK_TS_OFFSET 0x0029 -#define CAPT_CHUNK_TS_FD_OFFSET 0x0035 -#define CAPT_CHUNK_LINE_UPDATE_XFORM 0x0043 -#define CAPT_CHUNK_INTERLEAVE 0x0044 -#define CAPT_CHUNK_WTF 0x004e +#define CAPT_CHUNK_REPLY_CONFIG 0x0017 +#define CAPT_CHUNK_FINGER_DETECT 0x0026 +#define CAPT_CHUNK_IMAGE_RECON 0x002e +#define CAPT_CHUNK_2D_PARAMS 0x002f +#define CAPT_CHUNK_LINE_UPDATE 0x0030 +#define CAPT_CHUNK_TIMESLOT_2D 0x0034 +#define CAPT_CHUNK_TS_OFFSET 0x0029 +#define CAPT_CHUNK_TS_FD_OFFSET 0x0035 +#define CAPT_CHUNK_LINE_UPDATE_XFORM 0x0043 +#define CAPT_CHUNK_INTERLEAVE 0x0044 +#define CAPT_CHUNK_WTF 0x004e /* Capture program cookie for the ACM Config chunk */ -#define CAPT_CHUNK_ACM_CONFIG 0x002a -#define CAPT_CHUNK_CEM_CONFIG 0x002c +#define CAPT_CHUNK_ACM_CONFIG 0x002a +#define CAPT_CHUNK_CEM_CONFIG 0x002c diff --git a/libfprint/drivers/validity/validity_db.c b/libfprint/drivers/validity/validity_db.c index 29ca7892..a92e98a6 100644 --- a/libfprint/drivers/validity/validity_db.c +++ b/libfprint/drivers/validity/validity_db.c @@ -129,8 +129,8 @@ validity_db_build_cmd_get_user_storage (const gchar *name, /* cmd 0x4A: Get user by dbid * Format: 0x4A | dbid(2LE) | 0(2LE) | 0(2LE) */ guint8 * -validity_db_build_cmd_get_user (guint16 dbid, - gsize *out_len) +validity_db_build_cmd_get_user (guint16 dbid, + gsize *out_len) { guint8 *cmd = g_new0 (guint8, 7); @@ -166,10 +166,10 @@ validity_db_build_cmd_lookup_user (guint16 storage_dbid, } /* cmd 0x49: Get record value - * Format: 0x49 | dbid(2LE) */ +* Format: 0x49 | dbid(2LE) */ guint8 * -validity_db_build_cmd_get_record_value (guint16 dbid, - gsize *out_len) +validity_db_build_cmd_get_record_value (guint16 dbid, + gsize *out_len) { guint8 *cmd = g_new0 (guint8, 3); @@ -183,8 +183,8 @@ validity_db_build_cmd_get_record_value (guint16 dbid, /* cmd 0x46: Get record children * Format: 0x46 | dbid(2LE) */ guint8 * -validity_db_build_cmd_get_record_children (guint16 dbid, - gsize *out_len) +validity_db_build_cmd_get_record_children (guint16 dbid, + gsize *out_len) { guint8 *cmd = g_new0 (guint8, 3); @@ -223,8 +223,8 @@ validity_db_build_cmd_new_record (guint16 parent, /* cmd 0x48: Delete record * Format: 0x48 | dbid(2LE) */ guint8 * -validity_db_build_cmd_del_record (guint16 dbid, - gsize *out_len) +validity_db_build_cmd_del_record (guint16 dbid, + gsize *out_len) { guint8 *cmd = g_new0 (guint8, 3); @@ -266,8 +266,8 @@ validity_db_build_cmd_create_enrollment (gboolean start, /* cmd 0x68: Enrollment update start * PY format: pack('buffer[0]; if (transfer->actual_length >= 5) - fp_dbg ("Interrupt: type=0x%02x bytes=[%02x %02x %02x %02x %02x] (len=%" G_GSSIZE_FORMAT ")", - int_type, transfer->buffer[0], transfer->buffer[1], - transfer->buffer[2], transfer->buffer[3], transfer->buffer[4], - transfer->actual_length); + { + fp_dbg ("Interrupt: type=0x%02x bytes=[%02x %02x %02x %02x %02x] (len=%" G_GSSIZE_FORMAT ")", + int_type, transfer->buffer[0], transfer->buffer[1], + transfer->buffer[2], transfer->buffer[3], transfer->buffer[4], + transfer->actual_length); + } else - fp_dbg ("Interrupt: type=0x%02x (len=%" G_GSSIZE_FORMAT ")", - int_type, transfer->actual_length); + { + fp_dbg ("Interrupt: type=0x%02x (len=%" G_GSSIZE_FORMAT ")", + int_type, transfer->actual_length); + } /* Check if this is the interrupt we're waiting for */ if (int_type == (guint8) target_state) @@ -126,10 +130,8 @@ interrupt_cb (FpiUsbTransfer *transfer, if (int_type == 3 && transfer->actual_length >= 3) { if (!(transfer->buffer[2] & VALIDITY_INT_SCAN_COMPLETE)) - { - /* Not scan complete yet, keep waiting */ - goto read_again; - } + /* Not scan complete yet, keep waiting */ + goto read_again; /* Scan fully complete — reset retry counter */ self->scan_incomplete_count = 0; } @@ -223,9 +225,9 @@ enrollment_update_result_clear (EnrollmentUpdateResult *r) } gboolean -parse_enrollment_update_response (const guint8 *data, - gsize data_len, - EnrollmentUpdateResult *result) +parse_enrollment_update_response (const guint8 *data, + gsize data_len, + EnrollmentUpdateResult *result) { gsize pos = 0; guint16 declared_len; @@ -339,8 +341,8 @@ enroll_run_state (FpiSsm *ssm, if (self->cmd_response_status != VCSFW_STATUS_OK || !self->cmd_response_data || !validity_db_parse_user_storage (self->cmd_response_data, - self->cmd_response_len, - &self->list_storage)) + self->cmd_response_len, + &self->list_storage)) { /* No storage or parse error — skip cleanup, go to enrollment */ fpi_ssm_jump_to_state (ssm, ENROLL_START); @@ -525,17 +527,13 @@ enroll_run_state (FpiSsm *ssm, case ENROLL_CAPTURE_STOP_RECV: /* PY: no glow_end after capture — LED stays on. */ if (self->scan_incomplete_count > 0) - { - /* Incomplete scan: retry after a brief delay. - * glow_start at the top of the loop will reinitialize. - * PY: in the except block, just retries the whole loop. */ - fpi_ssm_jump_to_state_delayed (ssm, ENROLL_LED_ON, 3000); - } + /* Incomplete scan: retry after a brief delay. + * glow_start at the top of the loop will reinitialize. + * PY: in the except block, just retries the whole loop. */ + fpi_ssm_jump_to_state_delayed (ssm, ENROLL_LED_ON, 3000); else - { - /* Good scan — proceed to enrollment_update_start */ - fpi_ssm_next_state (ssm); - } + /* Good scan — proceed to enrollment_update_start */ + fpi_ssm_next_state (ssm); break; case ENROLL_UPDATE_START: diff --git a/libfprint/drivers/validity/validity_fwext.c b/libfprint/drivers/validity/validity_fwext.c index 6e89b522..9fb49fee 100644 --- a/libfprint/drivers/validity/validity_fwext.c +++ b/libfprint/drivers/validity/validity_fwext.c @@ -32,23 +32,23 @@ /* ---- Constants ---- */ -#define FWEXT_CHUNK_SIZE 0x1000 /* 4 KB per write_flash chunk */ -#define FWEXT_SIGNATURE_SIZE 256 /* RSA signature length */ -#define FWEXT_HEADER_DELIMITER 0x1A /* .xpfwext header end marker */ +#define FWEXT_CHUNK_SIZE 0x1000 /* 4 KB per write_flash chunk */ +#define FWEXT_SIGNATURE_SIZE 256 /* RSA signature length */ +#define FWEXT_HEADER_DELIMITER 0x1A /* .xpfwext header end marker */ -#define FWEXT_HW_REG_WRITE_ADDR 0x8000205C -#define FWEXT_HW_REG_WRITE_VALUE 7 -#define FWEXT_HW_REG_READ_ADDR 0x80002080 +#define FWEXT_HW_REG_WRITE_ADDR 0x8000205C +#define FWEXT_HW_REG_WRITE_VALUE 7 +#define FWEXT_HW_REG_READ_ADDR 0x80002080 /* Firmware partition */ -#define FWEXT_PARTITION 2 +#define FWEXT_PARTITION 2 /* Reboot command: 0x05 0x02 0x00 */ -#define VCSFW_CMD_REBOOT 0x05 -#define VCSFW_REBOOT_SUBCMD 0x02 +#define VCSFW_CMD_REBOOT 0x05 +#define VCSFW_REBOOT_SUBCMD 0x02 /* Cleanup command (call_cleanups): 0x1a */ -#define VCSFW_CMD_CLEANUP 0x1A +#define VCSFW_CMD_CLEANUP 0x1A /* ---- Firmware file search paths ---- */ @@ -67,10 +67,10 @@ static const gchar *firmware_search_paths[] = { * ================================================================ */ gboolean -validity_fwext_parse_fw_info (const guint8 *data, - gsize data_len, - guint16 status, - ValidityFwInfo *info) +validity_fwext_parse_fw_info (const guint8 *data, + gsize data_len, + guint16 status, + ValidityFwInfo *info) { memset (info, 0, sizeof (*info)); @@ -143,9 +143,9 @@ validity_fwext_get_firmware_name (guint16 vid, } gchar * -validity_fwext_find_firmware (guint16 vid, - guint16 pid, - GError **error) +validity_fwext_find_firmware (guint16 vid, + guint16 pid, + GError **error) { const gchar *filename = validity_fwext_get_firmware_name (vid, pid); @@ -238,10 +238,10 @@ validity_fwext_file_clear (ValidityFwextFile *fwext) * ================================================================ */ void -validity_fwext_build_write_hw_reg32 (guint32 addr, - guint32 value, - guint8 *cmd, - gsize *cmd_len) +validity_fwext_build_write_hw_reg32 (guint32 addr, + guint32 value, + guint8 *cmd, + gsize *cmd_len) { /* pack('vid, - ud->pid, - &dbe_len); + ud->pid, + &dbe_len); if (dbe == NULL || dbe_len == 0) { @@ -581,15 +581,11 @@ validity_fwext_upload_run_state (FpiSsm *ssm, } if (ud->write_offset < ud->fwext.payload_len) - { - /* More chunks to write -- loop back to db_write_enable */ - fpi_ssm_jump_to_state (ssm, FWEXT_SEND_DB_WRITE_ENABLE); - } + /* More chunks to write -- loop back to db_write_enable */ + fpi_ssm_jump_to_state (ssm, FWEXT_SEND_DB_WRITE_ENABLE); else - { - /* All chunks written -- proceed to signature */ - fpi_ssm_next_state (ssm); - } + /* All chunks written -- proceed to signature */ + fpi_ssm_next_state (ssm); break; case FWEXT_SEND_WRITE_SIGNATURE: @@ -684,7 +680,7 @@ validity_fwext_upload_ssm_new (FpDevice *dev) FwextUploadData *ud; ssm = fpi_ssm_new (dev, validity_fwext_upload_run_state, - FWEXT_NUM_STATES); + FWEXT_NUM_STATES); ud = g_new0 (FwextUploadData, 1); fpi_ssm_set_data (ssm, ud, fwext_upload_data_free); diff --git a/libfprint/drivers/validity/validity_fwext.h b/libfprint/drivers/validity/validity_fwext.h index e6ee31b8..8c0a2df2 100644 --- a/libfprint/drivers/validity/validity_fwext.h +++ b/libfprint/drivers/validity/validity_fwext.h @@ -35,11 +35,11 @@ typedef struct typedef struct { - gboolean loaded; - guint16 major; - guint16 minor; - guint32 buildtime; - guint16 module_count; + gboolean loaded; + guint16 major; + guint16 minor; + guint32 buildtime; + guint16 module_count; ValidityFwModule modules[32]; } ValidityFwInfo; @@ -84,56 +84,56 @@ typedef enum { /* ---- API ---- */ -gboolean validity_fwext_parse_fw_info (const guint8 *data, - gsize data_len, - guint16 status, - ValidityFwInfo *info); +gboolean validity_fwext_parse_fw_info (const guint8 *data, + gsize data_len, + guint16 status, + ValidityFwInfo *info); -gboolean validity_fwext_load_file (const gchar *filename, - ValidityFwextFile *fwext, - GError **error); +gboolean validity_fwext_load_file (const gchar *filename, + ValidityFwextFile *fwext, + GError **error); -void validity_fwext_file_clear (ValidityFwextFile *fwext); +void validity_fwext_file_clear (ValidityFwextFile *fwext); const gchar *validity_fwext_get_firmware_name (guint16 vid, guint16 pid); -gchar *validity_fwext_find_firmware (guint16 vid, - guint16 pid, - GError **error); +gchar *validity_fwext_find_firmware (guint16 vid, + guint16 pid, + GError **error); -void validity_fwext_build_write_hw_reg32 (guint32 addr, - guint32 value, - guint8 *cmd, - gsize *cmd_len); +void validity_fwext_build_write_hw_reg32 (guint32 addr, + guint32 value, + guint8 *cmd, + gsize *cmd_len); -void validity_fwext_build_read_hw_reg32 (guint32 addr, - guint8 *cmd, - gsize *cmd_len); +void validity_fwext_build_read_hw_reg32 (guint32 addr, + guint8 *cmd, + gsize *cmd_len); -gboolean validity_fwext_parse_read_hw_reg32 (const guint8 *data, - gsize data_len, - guint32 *value); +gboolean validity_fwext_parse_read_hw_reg32 (const guint8 *data, + gsize data_len, + guint32 *value); -void validity_fwext_build_write_flash (guint8 partition, - guint32 offset, - const guint8 *data, - gsize data_len, - guint8 *cmd, - gsize *cmd_len); +void validity_fwext_build_write_flash (guint8 partition, + guint32 offset, + const guint8 *data, + gsize data_len, + guint8 *cmd, + gsize *cmd_len); -void validity_fwext_build_write_fw_sig (guint8 partition, - const guint8 *signature, - gsize sig_len, - guint8 *cmd, - gsize *cmd_len); +void validity_fwext_build_write_fw_sig (guint8 partition, + const guint8 *signature, + gsize sig_len, + guint8 *cmd, + gsize *cmd_len); -void validity_fwext_build_reboot (guint8 *cmd, - gsize *cmd_len); +void validity_fwext_build_reboot (guint8 *cmd, + gsize *cmd_len); -const guint8 *validity_fwext_get_db_write_enable (guint16 vid, - guint16 pid, - gsize *len); +const guint8 *validity_fwext_get_db_write_enable (guint16 vid, + guint16 pid, + gsize *len); /* SSM entry point for upload state machine */ void validity_fwext_upload_run_state (FpiSsm *ssm, @@ -141,4 +141,4 @@ void validity_fwext_upload_run_state (FpiSsm *ssm, /* Create the fwext upload SSM with data attached. * Caller starts it via fpi_ssm_start(). */ -FpiSsm *validity_fwext_upload_ssm_new (FpDevice *dev); +FpiSsm *validity_fwext_upload_ssm_new (FpDevice *dev); diff --git a/libfprint/drivers/validity/validity_hal.c b/libfprint/drivers/validity/validity_hal.c index f92fd292..9532d2ab 100644 --- a/libfprint/drivers/validity/validity_hal.c +++ b/libfprint/drivers/validity/validity_hal.c @@ -162,10 +162,8 @@ const ValidityDeviceDesc * validity_hal_device_lookup_by_pid (guint16 vid, guint16 pid) { for (gsize i = 0; i < G_N_ELEMENTS (device_table); i++) - { - if (device_table[i].vid == vid && device_table[i].pid == pid) - return &device_table[i]; - } + if (device_table[i].vid == vid && device_table[i].pid == pid) + return &device_table[i]; return NULL; } diff --git a/libfprint/drivers/validity/validity_hal.h b/libfprint/drivers/validity/validity_hal.h index 9b8e0ee8..eb8ed913 100644 --- a/libfprint/drivers/validity/validity_hal.h +++ b/libfprint/drivers/validity/validity_hal.h @@ -80,10 +80,10 @@ typedef struct } ValidityDeviceDesc; /* Number of flash partition entries in the standard layout */ -#define VALIDITY_FLASH_NUM_PARTITIONS 5 +#define VALIDITY_FLASH_NUM_PARTITIONS 5 /* Partition signature size (RSA-2048) */ -#define VALIDITY_PARTITION_SIG_SIZE 256 +#define VALIDITY_PARTITION_SIG_SIZE 256 /* Look up device descriptor by ValidityDeviceType enum. * Returns NULL if dev_type is out of range. */ diff --git a/libfprint/drivers/validity/validity_pair.c b/libfprint/drivers/validity/validity_pair.c index 8735ce39..f5f2696b 100644 --- a/libfprint/drivers/validity/validity_pair.c +++ b/libfprint/drivers/validity/validity_pair.c @@ -79,7 +79,7 @@ validity_pair_state_free (ValidityPairState *state) * [partition_entries: count * 12 bytes each] * ================================================================ */ -#define FLASH_INFO_HEADER_SIZE 14 /* 7 × guint16 */ +#define FLASH_INFO_HEADER_SIZE 14 /* 7 × guint16 */ gboolean validity_pair_parse_flash_info (const guint8 *data, @@ -130,7 +130,7 @@ validity_pair_parse_flash_info (const guint8 *data, void validity_pair_serialize_partition (const ValidityPartition *part, - guint8 *out) + guint8 *out) { guint8 entry[12]; @@ -286,7 +286,7 @@ derive_hs_signing_key (void) * ================================================================ */ /* Certificate body size: 8 + 32 + 36 + 32 + 76 = 184 bytes */ -#define CERT_BODY_SIZE 184 +#define CERT_BODY_SIZE 184 guint8 * validity_pair_make_cert (const guint8 *client_public_x, @@ -362,6 +362,7 @@ validity_pair_encrypt_key (const guint8 *client_private, { /* Build plaintext: x + y + d = 96 bytes */ guint8 plaintext[96 + 16]; /* + max PKCS7 padding */ + memcpy (plaintext, client_public_x, 32); memcpy (plaintext + 32, client_public_y, 32); memcpy (plaintext + 64, client_private, 32); @@ -439,19 +440,20 @@ validity_pair_encrypt_key (const guint8 *client_private, guint8 * validity_pair_build_partition_flash_cmd (const ValidityFlashIcParams *flash_ic, - const ValidityFlashLayout *layout, - const guint8 *client_public_x, - const guint8 *client_public_y, - gsize *out_len) + const ValidityFlashLayout *layout, + const guint8 *client_public_x, + const guint8 *client_public_y, + gsize *out_len) { /* Build flash IC params body (hdr 0) */ guint8 ic_body[12]; + serialize_flash_params (flash_ic, ic_body); gsize hdr0_len; g_autofree guint8 *hdr0 = build_header (VALIDITY_HDR_FLASH_IC, - ic_body, sizeof (ic_body), - &hdr0_len); + ic_body, sizeof (ic_body), + &hdr0_len); /* Build partition table body (hdr 1): * [partition entries (48 bytes each)] + [RSA signature (256 bytes)] */ @@ -460,38 +462,36 @@ validity_pair_build_partition_flash_cmd (const ValidityFlashIcParams *flash_ic, g_autofree guint8 *ptbl_body = g_malloc0 (ptbl_body_len); for (gsize i = 0; i < layout->num_partitions; i++) - { - validity_pair_serialize_partition (&layout->partitions[i], - ptbl_body + (i * VALIDITY_PARTITION_ENTRY_SIZE)); - } + validity_pair_serialize_partition (&layout->partitions[i], + ptbl_body + (i * VALIDITY_PARTITION_ENTRY_SIZE)); memcpy (ptbl_body + (layout->num_partitions * VALIDITY_PARTITION_ENTRY_SIZE), layout->partition_sig, layout->partition_sig_len); gsize hdr1_len; g_autofree guint8 *hdr1 = build_header (VALIDITY_HDR_PARTITION_TABLE, - ptbl_body, ptbl_body_len, - &hdr1_len); + ptbl_body, ptbl_body_len, + &hdr1_len); /* Build client certificate (hdr 5) */ gsize cert_len; g_autofree guint8 *cert = validity_pair_make_cert (client_public_x, - client_public_y, - &cert_len); + client_public_y, + &cert_len); if (!cert) return NULL; gsize hdr5_len; g_autofree guint8 *hdr5 = build_header (VALIDITY_HDR_CLIENT_CERT, - cert, cert_len, - &hdr5_len); + cert, cert_len, + &hdr5_len); /* CA certificate (hdr 3) — from auto-generated constants */ gsize ca_cert_len = sizeof (ca_cert_hardcoded); gsize hdr3_len; g_autofree guint8 *hdr3 = build_header (VALIDITY_HDR_CA_CERT, - ca_cert_hardcoded, ca_cert_len, - &hdr3_len); + ca_cert_hardcoded, ca_cert_len, + &hdr3_len); /* Assemble: [4f 00 00 00 00] + hdr0 + hdr1 + hdr5 + hdr3 */ gsize cmd_prefix_len = 5; @@ -502,10 +502,14 @@ validity_pair_build_partition_flash_cmd (const ValidityFlashIcParams *flash_ic, /* bytes 1..4 are zero (already from g_malloc0) */ gsize offset = cmd_prefix_len; - memcpy (cmd + offset, hdr0, hdr0_len); offset += hdr0_len; - memcpy (cmd + offset, hdr1, hdr1_len); offset += hdr1_len; - memcpy (cmd + offset, hdr5, hdr5_len); offset += hdr5_len; - memcpy (cmd + offset, hdr3, hdr3_len); offset += hdr3_len; + memcpy (cmd + offset, hdr0, hdr0_len); + offset += hdr0_len; + memcpy (cmd + offset, hdr1, hdr1_len); + offset += hdr1_len; + memcpy (cmd + offset, hdr5, hdr5_len); + offset += hdr5_len; + memcpy (cmd + offset, hdr3, hdr3_len); + offset += hdr3_len; *out_len = total; return cmd; @@ -529,7 +533,7 @@ validity_pair_build_partition_flash_cmd (const ValidityFlashIcParams *flash_ic, * Remaining: 0xff padding to 0x1000 * ================================================================ */ -#define TLS_FLASH_IMAGE_SIZE 0x1000 +#define TLS_FLASH_IMAGE_SIZE 0x1000 static gsize append_flash_block (guint8 *buf, gsize offset, guint16 id, @@ -646,7 +650,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("GET_FLASH_INFO failed: status=0x%04x", self->cmd_response_status); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -657,7 +661,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("Failed to parse flash info"); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -679,7 +683,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("No HAL descriptor for dev_type=%u", self->dev_type); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); + fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); return; } @@ -765,7 +769,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("No HAL descriptor for dev_type=%u", self->dev_type); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); + fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); return; } @@ -780,7 +784,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("No reset_blob available for this device"); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); + fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED)); return; } @@ -797,7 +801,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("reset_blob failed: status=0x%04x", self->cmd_response_status); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } fpi_ssm_next_state (ssm); @@ -817,7 +821,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("ECDH key generation failed"); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); + fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); return; } @@ -860,7 +864,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("Failed to build partition_flash command"); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); + fpi_device_error_new (FP_DEVICE_ERROR_GENERAL)); return; } @@ -891,7 +895,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("partition_flash failed: status=0x%04x", self->cmd_response_status); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -953,7 +957,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("CMD 0x50 failed: status=0x%04x", self->cmd_response_status); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -972,7 +976,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("CMD 0x50 response too short: %" G_GSIZE_FORMAT, self->cmd_response_len); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -1015,7 +1019,7 @@ validity_pair_run_state (FpiSsm *ssm, memcpy (pub_uncompressed + 1, x_be, 32); memcpy (pub_uncompressed + 33, y_be, 32); OSSL_PARAM_BLD_push_octet_string (bld, OSSL_PKEY_PARAM_PUB_KEY, - pub_uncompressed, 65); + pub_uncompressed, 65); OSSL_PARAM *params = OSSL_PARAM_BLD_to_param (bld); EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL); @@ -1029,7 +1033,7 @@ validity_pair_run_state (FpiSsm *ssm, { fp_warn ("Failed to build ECDH server public key"); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } @@ -1087,7 +1091,7 @@ validity_pair_run_state (FpiSsm *ssm, } /* Set priv_key — the TLS handshake needs the actual EC private key - * (EVP_PKEY*) to sign cert_verify. We have it as ps->client_key. */ + * (EVP_PKEY*) to sign cert_verify. We have it as ps->client_key. */ if (self->tls.priv_key) EVP_PKEY_free (self->tls.priv_key); self->tls.priv_key = EVP_PKEY_dup (ps->client_key); @@ -1114,10 +1118,8 @@ validity_pair_run_state (FpiSsm *ssm, /* Ignore "nothing to commit" (0x0491) status */ if (self->cmd_response_status != VCSFW_STATUS_OK && self->cmd_response_status != 0x0491) - { - fp_warn ("cleanups failed: status=0x%04x", - self->cmd_response_status); - } + fp_warn ("cleanups failed: status=0x%04x", + self->cmd_response_status); fpi_ssm_next_state (ssm); } break; @@ -1131,8 +1133,8 @@ validity_pair_run_state (FpiSsm *ssm, * NOTE: do NOT overwrite self->open_ssm here — it must remain * pointing to the open SSM for pair_ssm_done to work. */ FpiSsm *tls_ssm = fpi_ssm_new (dev, - validity_tls_handshake_run_state, - TLS_HS_NUM_STATES); + validity_tls_handshake_run_state, + TLS_HS_NUM_STATES); fpi_ssm_start_subsm (ssm, tls_ssm); } break; @@ -1259,7 +1261,7 @@ validity_pair_run_state (FpiSsm *ssm, fp_warn ("write_flash failed: status=0x%04x", self->cmd_response_status); fpi_ssm_mark_failed (ssm, - fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); + fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); return; } fpi_ssm_next_state (ssm); diff --git a/libfprint/drivers/validity/validity_pair.h b/libfprint/drivers/validity/validity_pair.h index c9878b39..60d3149e 100644 --- a/libfprint/drivers/validity/validity_pair.h +++ b/libfprint/drivers/validity/validity_pair.h @@ -29,7 +29,7 @@ /* Forward declaration */ typedef struct _FpiDeviceValidity FpiDeviceValidity; -typedef struct _FpiSsm FpiSsm; +typedef struct _FpiSsm FpiSsm; /* Flash IC parameters — returned by CMD 0x3e (GET_FLASH_INFO) */ typedef struct @@ -72,25 +72,25 @@ typedef struct } ValidityPairState; /* Partition entry serialized format: 12 bytes data + 4 zero + 32 SHA-256 = 48 */ -#define VALIDITY_PARTITION_ENTRY_SIZE 48 +#define VALIDITY_PARTITION_ENTRY_SIZE 48 /* Client certificate size */ -#define VALIDITY_CLIENT_CERT_SIZE 444 +#define VALIDITY_CLIENT_CERT_SIZE 444 /* CMD 0x4f header IDs */ -#define VALIDITY_HDR_FLASH_IC 0 -#define VALIDITY_HDR_PARTITION_TABLE 1 -#define VALIDITY_HDR_CA_CERT 3 -#define VALIDITY_HDR_CLIENT_CERT 5 +#define VALIDITY_HDR_FLASH_IC 0 +#define VALIDITY_HDR_PARTITION_TABLE 1 +#define VALIDITY_HDR_CA_CERT 3 +#define VALIDITY_HDR_CLIENT_CERT 5 /* Encrypted private key format: 0x02 prefix + IV(16) + ciphertext(112) + HMAC(32) = 161 */ -#define VALIDITY_ENCRYPTED_KEY_PREFIX 0x02 +#define VALIDITY_ENCRYPTED_KEY_PREFIX 0x02 #define VALIDITY_ENCRYPTED_KEY_IV_SIZE 16 -#define VALIDITY_EC_COORD_SIZE 32 +#define VALIDITY_EC_COORD_SIZE 32 /* Flash partition IDs for erase during pairing */ static const guint8 pair_erase_partition_ids[] = { 1, 2, 5, 6, 4 }; -#define VALIDITY_PAIR_NUM_ERASE_STEPS G_N_ELEMENTS (pair_erase_partition_ids) +#define VALIDITY_PAIR_NUM_ERASE_STEPS G_N_ELEMENTS (pair_erase_partition_ids) /* ---- Helper functions (testable independently) ---- */ @@ -103,7 +103,7 @@ static const guint8 pair_erase_partition_ids[] = { 1, 2, 5, 6, 4 }; * [id:1][type:1][access_lvl:2LE][offset:4LE][size:4LE][zeros:4][SHA256:32] */ void validity_pair_serialize_partition (const ValidityPartition *part, - guint8 *out); + guint8 *out); /** * validity_pair_build_partition_flash_cmd: @@ -277,13 +277,13 @@ typedef enum { } ValidityPairSsmState; /* CMD 0x1a (cleanups/commit) */ -#define VCSFW_CMD_CLEANUPS 0x1a +#define VCSFW_CMD_CLEANUPS 0x1a /* CMD 0x50 (get ECDH server params after partition_flash) */ -#define VCSFW_CMD_GET_ECDH 0x50 +#define VCSFW_CMD_GET_ECDH 0x50 /* Reboot: 0x05 0x02 0x00 */ -#define VCSFW_CMD_REBOOT 0x05 +#define VCSFW_CMD_REBOOT 0x05 /** * validity_pair_ssm_new: diff --git a/libfprint/drivers/validity/validity_sensor.c b/libfprint/drivers/validity/validity_sensor.c index b9029b5b..9fe8a5a1 100644 --- a/libfprint/drivers/validity/validity_sensor.c +++ b/libfprint/drivers/validity/validity_sensor.c @@ -387,13 +387,9 @@ validity_device_info_lookup (guint16 major, guint8 masked_ver = entry->version & entry->version_mask; if (version == 0 || masked_ver == 0) - { - fuzzy_match = entry; - } + fuzzy_match = entry; else if ((guint8) version == masked_ver) - { - return entry; - } + return entry; } return fuzzy_match; @@ -407,10 +403,8 @@ const ValiditySensorTypeInfo * validity_sensor_type_info_lookup (guint16 sensor_type) { for (gsize i = 0; i < SENSOR_TYPE_INFO_TABLE_LEN; i++) - { - if (sensor_type_info_table[i].sensor_type == sensor_type) - return &sensor_type_info_table[i]; - } + if (sensor_type_info_table[i].sensor_type == sensor_type) + return &sensor_type_info_table[i]; return NULL; } diff --git a/libfprint/drivers/validity/validity_sensor.h b/libfprint/drivers/validity/validity_sensor.h index 1d593a5a..0ec29d31 100644 --- a/libfprint/drivers/validity/validity_sensor.h +++ b/libfprint/drivers/validity/validity_sensor.h @@ -72,9 +72,9 @@ typedef struct */ typedef struct { - ValiditySensorIdent ident; - const ValidityDeviceInfo *device_info; - const ValiditySensorTypeInfo *type_info; + ValiditySensorIdent ident; + const ValidityDeviceInfo *device_info; + const ValiditySensorTypeInfo *type_info; /* Factory calibration bits (raw response from cmd 0x6f) */ guint8 *factory_bits; @@ -122,5 +122,5 @@ gsize validity_sensor_build_factory_bits_cmd (guint16 tag, /* ---- Lifecycle ---- */ -void validity_sensor_state_init (ValiditySensorState *state); +void validity_sensor_state_init (ValiditySensorState *state); void validity_sensor_state_clear (ValiditySensorState *state); diff --git a/libfprint/drivers/validity/validity_tls.c b/libfprint/drivers/validity/validity_tls.c index 587a5e30..b6e7c8c5 100644 --- a/libfprint/drivers/validity/validity_tls.c +++ b/libfprint/drivers/validity/validity_tls.c @@ -93,6 +93,7 @@ validity_tls_prf (const guint8 *secret, /* A(1) = HMAC(secret, seed) */ EVP_MAC_CTX *ctx = EVP_MAC_CTX_new (mac); + EVP_MAC_init (ctx, secret, secret_len, prf_params); EVP_MAC_update (ctx, seed, seed_len); EVP_MAC_final (ctx, a, &hmac_len, sizeof (a)); @@ -174,6 +175,7 @@ validity_tls_derive_psk (ValidityTlsState *tls) { g_autofree gchar *product_name = NULL; g_autofree gchar *product_serial = NULL; + g_autoptr(GError) error_name = NULL; g_autoptr(GError) error_serial = NULL; @@ -400,6 +402,7 @@ validity_tls_wrap_app_data (ValidityTlsState *tls, /* Sign: plaintext || HMAC(sign_key, hdr || plaintext) */ gsize signed_len = cmd_len + TLS_HMAC_SIZE; guint8 *signed_data = g_malloc (signed_len); + memcpy (signed_data, cmd, cmd_len); tls_hmac_sign (tls->sign_key, TLS_CONTENT_APP_DATA, cmd, cmd_len, signed_data + cmd_len); @@ -974,6 +977,7 @@ hs_append_msg (GByteArray *buf, GChecksum *hash, guint8 type, const guint8 *body, gsize body_len) { guint8 hdr[4]; + hdr[0] = type; hdr[1] = (body_len >> 16) & 0xff; hdr[2] = (body_len >> 8) & 0xff; @@ -1172,7 +1176,7 @@ validity_tls_parse_server_hello (ValidityTlsState *tls, const guint8 *after_sessid = after_random + 1 + sess_id_len; guint16 suite = ((guint16) after_sessid[0] << 8) | - after_sessid[1]; + after_sessid[1]; if (suite != TLS_CS_ECDH_ECDSA_AES256_CBC_SHA) { g_set_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO, @@ -1238,6 +1242,7 @@ validity_tls_build_client_finish (ValidityTlsState *tls, gsize *out_len) /* ---- Generate ephemeral ECDH key pair ---- */ EVP_PKEY *params_key = NULL; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL); + EVP_PKEY_keygen_init (pctx); OSSL_PARAM gen_params[] = { OSSL_PARAM_utf8_string (OSSL_PKEY_PARAM_GROUP_NAME, (char *) "prime256v1", 0), @@ -1280,7 +1285,8 @@ validity_tls_build_client_finish (ValidityTlsState *tls, gsize *out_len) } { GChecksum *hc = g_checksum_copy (tls->handshake_hash); - guint8 hd[32]; gsize hl = 32; + guint8 hd[32]; + gsize hl = 32; g_checksum_get_digest (hc, hd, &hl); g_checksum_free (hc); GString *hex = g_string_new ("TLS hash after srv: "); @@ -1369,7 +1375,8 @@ validity_tls_build_client_finish (ValidityTlsState *tls, gsize *out_len) g_byte_array_free (wrapped2, TRUE); { GChecksum *hc = g_checksum_copy (tls->handshake_hash); - guint8 hd[32]; gsize hl = 32; + guint8 hd[32]; + gsize hl = 32; g_checksum_get_digest (hc, hd, &hl); g_checksum_free (hc); GString *hex = g_string_new ("TLS hash after cert: "); @@ -1404,7 +1411,8 @@ validity_tls_build_client_finish (ValidityTlsState *tls, gsize *out_len) TLS_HS_CLIENT_KEY_EXCHANGE, kex_body, kex_body_len); { GChecksum *hc = g_checksum_copy (tls->handshake_hash); - guint8 hd[32]; gsize hl = 32; + guint8 hd[32]; + gsize hl = 32; g_checksum_get_digest (hc, hd, &hl); g_checksum_free (hc); GString *hex = g_string_new ("TLS hash after kex: "); @@ -1748,8 +1756,8 @@ validity_tls_flash_read_run_state (FpiSsm *ssm, if (!self->cmd_response_data || self->cmd_response_len == 0) { fpi_ssm_mark_failed (ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, - "TLS flash read: empty response")); + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "TLS flash read: empty response")); return; } @@ -1851,8 +1859,8 @@ validity_tls_handshake_run_state (FpiSsm *ssm, if (!self->cmd_response_data) { fpi_ssm_mark_failed (ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, - "TLS handshake: no ServerHello response")); + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "TLS handshake: no ServerHello response")); return; } @@ -1896,8 +1904,8 @@ validity_tls_handshake_run_state (FpiSsm *ssm, if (!self->cmd_response_data) { fpi_ssm_mark_failed (ssm, - fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, - "TLS handshake: no ServerFinish response")); + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "TLS handshake: no ServerFinish response")); return; } diff --git a/libfprint/drivers/validity/validity_tls.h b/libfprint/drivers/validity/validity_tls.h index 13e8c740..6c5efc86 100644 --- a/libfprint/drivers/validity/validity_tls.h +++ b/libfprint/drivers/validity/validity_tls.h @@ -25,58 +25,58 @@ #include /* TLS record content types */ -#define TLS_CONTENT_CHANGE_CIPHER 0x14 -#define TLS_CONTENT_HANDSHAKE 0x16 -#define TLS_CONTENT_APP_DATA 0x17 +#define TLS_CONTENT_CHANGE_CIPHER 0x14 +#define TLS_CONTENT_HANDSHAKE 0x16 +#define TLS_CONTENT_APP_DATA 0x17 /* TLS version 1.2 */ -#define TLS_VERSION_MAJOR 0x03 -#define TLS_VERSION_MINOR 0x03 +#define TLS_VERSION_MAJOR 0x03 +#define TLS_VERSION_MINOR 0x03 /* TLS handshake message types */ -#define TLS_HS_CLIENT_HELLO 0x01 -#define TLS_HS_SERVER_HELLO 0x02 -#define TLS_HS_CERTIFICATE 0x0B -#define TLS_HS_CERT_REQUEST 0x0D -#define TLS_HS_SERVER_HELLO_DONE 0x0E -#define TLS_HS_CERT_VERIFY 0x0F +#define TLS_HS_CLIENT_HELLO 0x01 +#define TLS_HS_SERVER_HELLO 0x02 +#define TLS_HS_CERTIFICATE 0x0B +#define TLS_HS_CERT_REQUEST 0x0D +#define TLS_HS_SERVER_HELLO_DONE 0x0E +#define TLS_HS_CERT_VERIFY 0x0F #define TLS_HS_CLIENT_KEY_EXCHANGE 0x10 -#define TLS_HS_FINISHED 0x14 +#define TLS_HS_FINISHED 0x14 /* Cipher suite */ -#define TLS_CS_ECDH_ECDSA_AES256_CBC_SHA 0xC005 +#define TLS_CS_ECDH_ECDSA_AES256_CBC_SHA 0xC005 /* Key/block sizes */ -#define TLS_AES_KEY_SIZE 32 -#define TLS_IV_SIZE 16 -#define TLS_HMAC_SIZE 32 -#define TLS_AES_BLOCK_SIZE 16 -#define TLS_MASTER_SECRET_SIZE 48 -#define TLS_KEY_BLOCK_SIZE 0x120 -#define TLS_RANDOM_SIZE 32 -#define TLS_VERIFY_DATA_SIZE 12 +#define TLS_AES_KEY_SIZE 32 +#define TLS_IV_SIZE 16 +#define TLS_HMAC_SIZE 32 +#define TLS_AES_BLOCK_SIZE 16 +#define TLS_MASTER_SECRET_SIZE 48 +#define TLS_KEY_BLOCK_SIZE 0x120 +#define TLS_RANDOM_SIZE 32 +#define TLS_VERIFY_DATA_SIZE 12 /* VCSFW TLS command prefix */ -#define TLS_CMD_PREFIX_SIZE 4 +#define TLS_CMD_PREFIX_SIZE 4 /* Flash block IDs */ -#define TLS_FLASH_BLOCK_EMPTY0 0x0000 -#define TLS_FLASH_BLOCK_EMPTY1 0x0001 -#define TLS_FLASH_BLOCK_EMPTY2 0x0002 -#define TLS_FLASH_BLOCK_CERT 0x0003 -#define TLS_FLASH_BLOCK_PRIVKEY 0x0004 -#define TLS_FLASH_BLOCK_CA_CERT 0x0005 -#define TLS_FLASH_BLOCK_ECDH 0x0006 -#define TLS_FLASH_BLOCK_END 0xFFFF +#define TLS_FLASH_BLOCK_EMPTY0 0x0000 +#define TLS_FLASH_BLOCK_EMPTY1 0x0001 +#define TLS_FLASH_BLOCK_EMPTY2 0x0002 +#define TLS_FLASH_BLOCK_CERT 0x0003 +#define TLS_FLASH_BLOCK_PRIVKEY 0x0004 +#define TLS_FLASH_BLOCK_CA_CERT 0x0005 +#define TLS_FLASH_BLOCK_ECDH 0x0006 +#define TLS_FLASH_BLOCK_END 0xFFFF /* Flash block header: [id:2 LE][size:2 LE][sha256:32] */ -#define TLS_FLASH_BLOCK_HEADER_SIZE (2 + 2 + 32) +#define TLS_FLASH_BLOCK_HEADER_SIZE (2 + 2 + 32) /* ECDH key blob offsets */ -#define TLS_ECDH_BLOB_SIZE 0x90 -#define TLS_ECDH_X_OFFSET 0x08 -#define TLS_ECDH_Y_OFFSET 0x4C -#define TLS_EC_COORD_SIZE 0x20 +#define TLS_ECDH_BLOB_SIZE 0x90 +#define TLS_ECDH_X_OFFSET 0x08 +#define TLS_ECDH_Y_OFFSET 0x4C +#define TLS_EC_COORD_SIZE 0x20 /* Forward declaration */ typedef struct _FpiDeviceValidity FpiDeviceValidity; @@ -144,41 +144,41 @@ typedef enum { /* ---- Public API ---- */ -void validity_tls_init (ValidityTlsState *tls); -void validity_tls_free (ValidityTlsState *tls); +void validity_tls_init (ValidityTlsState *tls); +void validity_tls_free (ValidityTlsState *tls); -void validity_tls_derive_psk (ValidityTlsState *tls); +void validity_tls_derive_psk (ValidityTlsState *tls); -gboolean validity_tls_parse_flash (ValidityTlsState *tls, - const guint8 *data, - gsize data_len, - GError **error); +gboolean validity_tls_parse_flash (ValidityTlsState *tls, + const guint8 *data, + gsize data_len, + GError **error); /* PRF — exported for testing */ -void validity_tls_prf (const guint8 *secret, - gsize secret_len, - const guint8 *seed, - gsize seed_len, - guint8 *output, - gsize output_len); +void validity_tls_prf (const guint8 *secret, + gsize secret_len, + const guint8 *seed, + gsize seed_len, + guint8 *output, + gsize output_len); /* Encrypt/decrypt for TLS app data */ -guint8 *validity_tls_encrypt (ValidityTlsState *tls, - const guint8 *plaintext, - gsize plaintext_len, - gsize *out_len); +guint8 *validity_tls_encrypt (ValidityTlsState *tls, + const guint8 *plaintext, + gsize plaintext_len, + gsize *out_len); -guint8 *validity_tls_decrypt (ValidityTlsState *tls, - const guint8 *ciphertext, - gsize ciphertext_len, - gsize *out_len, - GError **error); +guint8 *validity_tls_decrypt (ValidityTlsState *tls, + const guint8 *ciphertext, + gsize ciphertext_len, + gsize *out_len, + GError **error); /* Build TLS app_data record wrapping a VCSFW command */ -guint8 *validity_tls_wrap_app_data (ValidityTlsState *tls, - const guint8 *cmd, - gsize cmd_len, - gsize *out_len); +guint8 *validity_tls_wrap_app_data (ValidityTlsState *tls, + const guint8 *cmd, + gsize cmd_len, + gsize *out_len); /* Parse TLS response, returning decrypted app_data */ guint8 *validity_tls_unwrap_response (ValidityTlsState *tls, diff --git a/libfprint/drivers/validity/validity_verify.c b/libfprint/drivers/validity/validity_verify.c index ee2c1aa5..6a9f3712 100644 --- a/libfprint/drivers/validity/validity_verify.c +++ b/libfprint/drivers/validity/validity_verify.c @@ -86,13 +86,17 @@ verify_interrupt_cb (FpiUsbTransfer *transfer, int_type = transfer->buffer[0]; if (transfer->actual_length >= 5) - fp_dbg ("Verify interrupt: type=0x%02x bytes=[%02x %02x %02x %02x %02x] (len=%" G_GSSIZE_FORMAT ")", - int_type, transfer->buffer[0], transfer->buffer[1], - transfer->buffer[2], transfer->buffer[3], transfer->buffer[4], - transfer->actual_length); + { + fp_dbg ("Verify interrupt: type=0x%02x bytes=[%02x %02x %02x %02x %02x] (len=%" G_GSSIZE_FORMAT ")", + int_type, transfer->buffer[0], transfer->buffer[1], + transfer->buffer[2], transfer->buffer[3], transfer->buffer[4], + transfer->actual_length); + } else - fp_dbg ("Verify interrupt: type=0x%02x (len=%" G_GSSIZE_FORMAT ")", - int_type, transfer->actual_length); + { + fp_dbg ("Verify interrupt: type=0x%02x (len=%" G_GSSIZE_FORMAT ")", + int_type, transfer->actual_length); + } /* During match wait, type 3 = match found, type 5 = no match */ if (fpi_ssm_get_cur_state (ssm) == VERIFY_WAIT_MATCH_INT) @@ -524,10 +528,8 @@ verify_ssm_done (FpiSsm *ssm, gboolean have_match = FALSE; if (self->bulk_data && self->bulk_data_len > 0) - { - if (validity_parse_match_result (self->bulk_data, self->bulk_data_len, &match)) - have_match = match.matched; - } + if (validity_parse_match_result (self->bulk_data, self->bulk_data_len, &match)) + have_match = match.matched; if (self->identify_mode) { @@ -643,8 +645,8 @@ list_run_state (FpiSsm *ssm, if (!self->cmd_response_data || !validity_db_parse_user_storage (self->cmd_response_data, - self->cmd_response_len, - &self->list_storage)) + self->cmd_response_len, + &self->list_storage)) { fp_info ("Failed to parse user storage — no enrolled prints"); fpi_ssm_jump_to_state (ssm, LIST_DONE); @@ -796,8 +798,8 @@ delete_run_state (FpiSsm *ssm, validity_user_storage_clear (&self->list_storage); if (!self->cmd_response_data || !validity_db_parse_user_storage (self->cmd_response_data, - self->cmd_response_len, - &self->list_storage)) + self->cmd_response_len, + &self->list_storage)) { fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND)); @@ -963,8 +965,8 @@ clear_run_state (FpiSsm *ssm, if (self->cmd_response_status != VCSFW_STATUS_OK || !self->cmd_response_data || !validity_db_parse_user_storage (self->cmd_response_data, - self->cmd_response_len, - &self->list_storage)) + self->cmd_response_len, + &self->list_storage)) { /* No storage or parse error — nothing to clear */ fpi_ssm_jump_to_state (ssm, CLEAR_DONE); diff --git a/libfprint/drivers/validity/vcsfw_protocol.c b/libfprint/drivers/validity/vcsfw_protocol.c index 13b4697a..3058ab42 100644 --- a/libfprint/drivers/validity/vcsfw_protocol.c +++ b/libfprint/drivers/validity/vcsfw_protocol.c @@ -28,9 +28,9 @@ /* ---- VcsfwCmdData lifecycle ---- */ VcsfwCmdData * -vcsfw_cmd_data_new (const guint8 *cmd, - gsize cmd_len, - VcsfwCmdCallback callback) +vcsfw_cmd_data_new (const guint8 *cmd, + gsize cmd_len, + VcsfwCmdCallback callback) { VcsfwCmdData *data = g_new0 (VcsfwCmdData, 1); @@ -186,7 +186,7 @@ vcsfw_cmd_send (FpiDeviceValidity *self, cmd_data = vcsfw_cmd_data_new (cmd, cmd_len, callback); ssm = fpi_ssm_new (FP_DEVICE (self), vcsfw_cmd_run_state, - VCSFW_CMD_STATE_NUM_STATES); + VCSFW_CMD_STATE_NUM_STATES); fpi_ssm_set_data (ssm, cmd_data, vcsfw_cmd_data_free); self->cmd_ssm = ssm; @@ -286,11 +286,13 @@ tls_cmd_receive_cb (FpiUsbTransfer *transfer, g_free (decrypted); if (cmd_data->callback) - cmd_data->callback (self, - self->cmd_response_data, - self->cmd_response_len, - status, - NULL); + { + cmd_data->callback (self, + self->cmd_response_data, + self->cmd_response_len, + status, + NULL); + } fpi_ssm_mark_completed (transfer->ssm); } @@ -358,7 +360,7 @@ vcsfw_tls_cmd_send (FpiDeviceValidity *self, cmd_data = vcsfw_cmd_data_new (cmd, cmd_len, callback); ssm = fpi_ssm_new (FP_DEVICE (self), vcsfw_tls_cmd_run_state, - VCSFW_TLS_CMD_STATE_NUM_STATES); + VCSFW_TLS_CMD_STATE_NUM_STATES); fpi_ssm_set_data (ssm, cmd_data, vcsfw_cmd_data_free); self->cmd_ssm = ssm; @@ -372,8 +374,8 @@ vcsfw_tls_cmd_send (FpiDeviceValidity *self, /* ---- GET_VERSION (cmd 0x01) response parser ---- */ gboolean -vcsfw_parse_version (const guint8 *data, - gsize data_len, +vcsfw_parse_version (const guint8 *data, + gsize data_len, ValidityVersionInfo *info) { FpiByteReader reader; diff --git a/libfprint/drivers/validity/vcsfw_protocol.h b/libfprint/drivers/validity/vcsfw_protocol.h index e00d5c2a..b961fcc8 100644 --- a/libfprint/drivers/validity/vcsfw_protocol.h +++ b/libfprint/drivers/validity/vcsfw_protocol.h @@ -23,42 +23,42 @@ #include "validity.h" /* ---- VCSFW Command IDs (pre-TLS) ---- */ -#define VCSFW_CMD_GET_VERSION 0x01 -#define VCSFW_CMD_READ_HW_REG32 0x07 -#define VCSFW_CMD_WRITE_HW_REG32 0x08 -#define VCSFW_CMD_UNKNOWN_INIT 0x19 -#define VCSFW_CMD_GET_FLASH_INFO 0x3E -#define VCSFW_CMD_READ_FLASH 0x40 -#define VCSFW_CMD_WRITE_FLASH 0x41 -#define VCSFW_CMD_WRITE_FW_SIG 0x42 -#define VCSFW_CMD_GET_FW_INFO 0x43 -#define VCSFW_CMD_PARTITION_FLASH 0x4F +#define VCSFW_CMD_GET_VERSION 0x01 +#define VCSFW_CMD_READ_HW_REG32 0x07 +#define VCSFW_CMD_WRITE_HW_REG32 0x08 +#define VCSFW_CMD_UNKNOWN_INIT 0x19 +#define VCSFW_CMD_GET_FLASH_INFO 0x3E +#define VCSFW_CMD_READ_FLASH 0x40 +#define VCSFW_CMD_WRITE_FLASH 0x41 +#define VCSFW_CMD_WRITE_FW_SIG 0x42 +#define VCSFW_CMD_GET_FW_INFO 0x43 +#define VCSFW_CMD_PARTITION_FLASH 0x4F /* ---- VCSFW Command IDs (post-TLS, via tls.app()) ---- */ -#define VCSFW_CMD_CAPTURE 0x02 -#define VCSFW_CMD_CAPTURE_STOP 0x04 -#define VCSFW_CMD_GLOW_START 0x39 -#define VCSFW_CMD_ERASE_FLASH 0x3F -#define VCSFW_CMD_DB_INFO 0x45 +#define VCSFW_CMD_CAPTURE 0x02 +#define VCSFW_CMD_CAPTURE_STOP 0x04 +#define VCSFW_CMD_GLOW_START 0x39 +#define VCSFW_CMD_ERASE_FLASH 0x3F +#define VCSFW_CMD_DB_INFO 0x45 #define VCSFW_CMD_GET_RECORD_CHILDREN 0x46 -#define VCSFW_CMD_NEW_RECORD 0x47 -#define VCSFW_CMD_DEL_RECORD 0x48 -#define VCSFW_CMD_GET_RECORD_VALUE 0x49 -#define VCSFW_CMD_GET_USER 0x4A -#define VCSFW_CMD_GET_USER_STORAGE 0x4B -#define VCSFW_CMD_GET_PRG_STATUS 0x51 -#define VCSFW_CMD_MATCH_FINGER 0x5E -#define VCSFW_CMD_GET_MATCH_RESULT 0x60 -#define VCSFW_CMD_MATCH_CLEANUP 0x62 +#define VCSFW_CMD_NEW_RECORD 0x47 +#define VCSFW_CMD_DEL_RECORD 0x48 +#define VCSFW_CMD_GET_RECORD_VALUE 0x49 +#define VCSFW_CMD_GET_USER 0x4A +#define VCSFW_CMD_GET_USER_STORAGE 0x4B +#define VCSFW_CMD_GET_PRG_STATUS 0x51 +#define VCSFW_CMD_MATCH_FINGER 0x5E +#define VCSFW_CMD_GET_MATCH_RESULT 0x60 +#define VCSFW_CMD_MATCH_CLEANUP 0x62 #define VCSFW_CMD_ENROLLMENT_UPDATE_START 0x68 -#define VCSFW_CMD_CREATE_ENROLLMENT 0x69 -#define VCSFW_CMD_ENROLLMENT_UPDATE 0x6B -#define VCSFW_CMD_GET_FACTORY_BITS 0x6F -#define VCSFW_CMD_IDENTIFY_SENSOR 0x75 +#define VCSFW_CMD_CREATE_ENROLLMENT 0x69 +#define VCSFW_CMD_ENROLLMENT_UPDATE 0x6B +#define VCSFW_CMD_GET_FACTORY_BITS 0x6F +#define VCSFW_CMD_IDENTIFY_SENSOR 0x75 /* ---- VCSFW Response Status Codes ---- */ -#define VCSFW_STATUS_OK 0x0000 -#define VCSFW_STATUS_NO_FW 0xB004 +#define VCSFW_STATUS_OK 0x0000 +#define VCSFW_STATUS_NO_FW 0xB004 /* ---- Callback types ---- */ @@ -105,9 +105,9 @@ typedef struct void vcsfw_cmd_run_state (FpiSsm *ssm, FpDevice *dev); -VcsfwCmdData *vcsfw_cmd_data_new (const guint8 *cmd, - gsize cmd_len, - VcsfwCmdCallback callback); +VcsfwCmdData *vcsfw_cmd_data_new (const guint8 *cmd, + gsize cmd_len, + VcsfwCmdCallback callback); void vcsfw_cmd_data_free (gpointer data); @@ -126,6 +126,6 @@ void vcsfw_tls_cmd_send (FpiDeviceValidity *self, gsize cmd_len, VcsfwCmdCallback callback); -gboolean vcsfw_parse_version (const guint8 *data, - gsize data_len, +gboolean vcsfw_parse_version (const guint8 *data, + gsize data_len, ValidityVersionInfo *info); diff --git a/tests/test-validity-capture.c b/tests/test-validity-capture.c index 67149b2c..ef9b81c9 100644 --- a/tests/test-validity-capture.c +++ b/tests/test-validity-capture.c @@ -137,7 +137,7 @@ test_decode_insn_noop (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 1, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_NOOP); g_assert_cmpuint (len, ==, 1); g_assert_cmpuint (n_ops, ==, 0); @@ -158,7 +158,7 @@ test_decode_insn_call (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 3, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_CALL); g_assert_cmpuint (len, ==, 3); g_assert_cmpuint (n_ops, ==, 3); @@ -180,7 +180,7 @@ test_decode_insn_call_repeat_zero (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 3, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_CALL); g_assert_cmpuint (operands[2], ==, 0x100); } @@ -201,7 +201,7 @@ test_decode_insn_regwrite (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 3, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_REG_WRITE); g_assert_cmpuint (len, ==, 3); g_assert_cmpuint (n_ops, ==, 2); @@ -222,7 +222,7 @@ test_decode_insn_enable_rx (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 2, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_ENABLE_RX); g_assert_cmpuint (len, ==, 2); g_assert_cmpuint (n_ops, ==, 1); @@ -243,7 +243,7 @@ test_decode_insn_sample (void) guint32 operands[3]; g_assert_true (validity_capture_decode_insn (data, 1, &opcode, &len, - operands, &n_ops)); + operands, &n_ops)); g_assert_cmpuint (opcode, ==, TST_OP_SAMPLE); g_assert_cmpuint (len, ==, 1); g_assert_cmpuint (n_ops, ==, 2); @@ -269,19 +269,19 @@ test_find_nth_insn (void) /* 1st NOOP is at offset 0 */ g_assert_cmpint (validity_capture_find_nth_insn (data, sizeof (data), - TST_OP_NOOP, 1), ==, 0); + TST_OP_NOOP, 1), ==, 0); /* 2nd NOOP is at offset 1 */ g_assert_cmpint (validity_capture_find_nth_insn (data, sizeof (data), - TST_OP_NOOP, 2), ==, 1); + TST_OP_NOOP, 2), ==, 1); /* 3rd NOOP is at offset 5 */ g_assert_cmpint (validity_capture_find_nth_insn (data, sizeof (data), - TST_OP_NOOP, 3), ==, 5); + TST_OP_NOOP, 3), ==, 5); /* 1st Call is at offset 2 */ g_assert_cmpint (validity_capture_find_nth_insn (data, sizeof (data), - TST_OP_CALL, 1), ==, 2); + TST_OP_CALL, 1), ==, 2); /* No 2nd Call */ g_assert_cmpint (validity_capture_find_nth_insn (data, sizeof (data), - TST_OP_CALL, 2), ==, -1); + TST_OP_CALL, 2), ==, -1); } /* ================================================================ @@ -300,13 +300,13 @@ test_find_nth_regwrite (void) /* Find 1st write to 0x8000203C → offset 3 */ g_assert_cmpint (validity_capture_find_nth_regwrite (data, sizeof (data), - 0x8000203c, 1), ==, 3); + 0x8000203c, 1), ==, 3); /* No 2nd write to 0x8000203C */ g_assert_cmpint (validity_capture_find_nth_regwrite (data, sizeof (data), - 0x8000203c, 2), ==, -1); + 0x8000203c, 2), ==, -1); /* Find 1st write to 0x80002000 → offset 0 */ g_assert_cmpint (validity_capture_find_nth_regwrite (data, sizeof (data), - 0x80002000, 1), ==, 0); + 0x80002000, 1), ==, 0); } /* ================================================================ @@ -326,7 +326,7 @@ test_patch_timeslot_table (void) /* Multiply by 2, with inc_address=TRUE */ g_assert_true (validity_capture_patch_timeslot_table (data, sizeof (data), - TRUE, 2)); + TRUE, 2)); /* repeat becomes 3*2=6 */ g_assert_cmpuint (data[2], ==, 6); @@ -348,7 +348,7 @@ test_patch_timeslot_table_no_mult_for_repeat1 (void) }; g_assert_true (validity_capture_patch_timeslot_table (data, sizeof (data), - TRUE, 4)); + TRUE, 4)); /* repeat stays 1 (not multiplied because <= 1) */ g_assert_cmpuint (data[2], ==, 1); /* address NOT incremented */ @@ -366,7 +366,7 @@ test_bitpack_uniform (void) { guint8 values[] = { 0x42, 0x42, 0x42, 0x42 }; guint8 v0, v1; - gsize out_len; + gsize out_len; guint8 *packed = validity_capture_bitpack (values, 4, &v0, &v1, &out_len); @@ -389,7 +389,7 @@ test_bitpack_range (void) { guint8 values[] = { 10, 11, 12, 13 }; guint8 v0, v1; - gsize out_len; + gsize out_len; guint8 *packed = validity_capture_bitpack (values, 4, &v0, &v1, &out_len); @@ -500,6 +500,7 @@ test_factory_bits_no_subtag3 (void) { /* Build response with only subtag=7 (no subtag=3) */ guint8 buf[32]; + FP_WRITE_UINT32_LE (buf, 0); /* wtf */ FP_WRITE_UINT32_LE (buf + 4, 1); /* entries=1 */ @@ -515,8 +516,8 @@ test_factory_bits_no_subtag3 (void) gsize cv_len = 0; gboolean ok = validity_capture_parse_factory_bits (buf, 25, - &cv, &cv_len, - NULL, NULL); + &cv, &cv_len, + NULL, NULL); g_assert_false (ok); g_assert_null (cv); } @@ -534,7 +535,7 @@ test_average_frames_interleave2 (void) guint16 bytes_per_line = 4; guint16 lines_per_calibration_data = 2; guint16 lines_per_frame = 4; /* 2 cal lines * 2 interleave */ - guint8 calibration_frames = 1; + guint8 calibration_frames = 1; /* Single frame: 4 lines * 4 bytes = 16 bytes */ guint8 raw[] = { @@ -582,8 +583,8 @@ test_clean_slate_roundtrip (void) gsize slate_len = 0; guint8 *slate = validity_capture_build_clean_slate (test_data, - sizeof (test_data), - &slate_len); + sizeof (test_data), + &slate_len); g_assert_nonnull (slate); g_assert_cmpuint (slate_len, >, 68); @@ -641,9 +642,9 @@ test_led_commands (void) g_assert_nonnull (start_cmd); g_assert_nonnull (end_cmd); - /* Both should be 128 bytes (LED control payload) */ - g_assert_cmpuint (start_len, ==, 128); - g_assert_cmpuint (end_len, ==, 128); + /* Both should be 125 bytes (LED control payload) */ + g_assert_cmpuint (start_len, ==, 125); + g_assert_cmpuint (end_len, ==, 125); /* Both should start with cmd byte 0x39 */ g_assert_cmpuint (start_cmd[0], ==, 0x39); @@ -663,6 +664,7 @@ test_capture_prog_lookup (void) /* Known: firmware 6.x, dev_type 0xb5 */ const guint8 *prog = validity_capture_prog_lookup (6, 7, 0x00b5, &len); + g_assert_nonnull (prog); g_assert_cmpuint (len, >, 0); @@ -676,9 +678,12 @@ test_capture_prog_lookup (void) gboolean has_acm = FALSE, has_tst = FALSE, has_2d = FALSE; for (gsize i = 0; i < n_chunks; i++) { - if (chunks[i].type == 0x002a) has_acm = TRUE; - if (chunks[i].type == CAPT_CHUNK_TIMESLOT_2D) has_tst = TRUE; - if (chunks[i].type == CAPT_CHUNK_2D_PARAMS) has_2d = TRUE; + if (chunks[i].type == 0x002a) + has_acm = TRUE; + if (chunks[i].type == CAPT_CHUNK_TIMESLOT_2D) + has_tst = TRUE; + if (chunks[i].type == CAPT_CHUNK_2D_PARAMS) + has_2d = TRUE; } g_assert_true (has_acm); g_assert_true (has_tst); @@ -737,8 +742,8 @@ test_capture_state_setup (void) validity_capture_state_init (&state); gboolean ok = validity_capture_state_setup (&state, type_info, - 0x00b5, 6, 7, - fb->data, fb->len); + 0x00b5, 6, 7, + fb->data, fb->len); g_assert_true (ok); g_assert_true (state.is_type1_device); @@ -795,8 +800,8 @@ test_build_cmd_02_header (void) gsize cmd_len = 0; guint8 *cmd = validity_capture_build_cmd_02 (&state, type_info, - VALIDITY_CAPTURE_CALIBRATE, - &cmd_len); + VALIDITY_CAPTURE_CALIBRATE, + &cmd_len); g_assert_nonnull (cmd); g_assert_cmpuint (cmd_len, >=, 5); @@ -823,8 +828,8 @@ test_build_cmd_02_header (void) /* Test IDENTIFY mode: req_lines should be 0 */ cmd = validity_capture_build_cmd_02 (&state, type_info, - VALIDITY_CAPTURE_IDENTIFY, - &cmd_len); + VALIDITY_CAPTURE_IDENTIFY, + &cmd_len); g_assert_nonnull (cmd); g_assert_cmpuint (FP_READ_UINT16_LE (cmd + 3), ==, 0); g_free (cmd); @@ -848,12 +853,12 @@ test_calibration_processing (void) }; guint8 *calib = NULL; - gsize calib_len = 0; + gsize calib_len = 0; /* First call: initializes calib_data */ validity_capture_process_calibration (&calib, &calib_len, - frame, sizeof (frame), - bytes_per_line); + frame, sizeof (frame), + bytes_per_line); g_assert_nonnull (calib); g_assert_cmpuint (calib_len, ==, 16); @@ -869,8 +874,8 @@ test_calibration_processing (void) /* Second call with same frame: accumulate */ validity_capture_process_calibration (&calib, &calib_len, - frame, sizeof (frame), - bytes_per_line); + frame, sizeof (frame), + bytes_per_line); /* add(0, 0) = 0, so data bytes still 0 */ for (int i = 8; i < 16; i++) diff --git a/tests/test-validity-db.c b/tests/test-validity-db.c index dbed6cfe..6d040c7d 100644 --- a/tests/test-validity-db.c +++ b/tests/test-validity-db.c @@ -165,6 +165,7 @@ test_cmd_create_enrollment (void) /* Start enrollment */ g_autofree guint8 *cmd_start = validity_db_build_cmd_create_enrollment (TRUE, &len); + g_assert_nonnull (cmd_start); g_assert_cmpuint (len, ==, 5); g_assert_cmpuint (cmd_start[0], ==, VCSFW_CMD_CREATE_ENROLLMENT); @@ -267,6 +268,7 @@ test_cmd_get_prg_status (void) gsize len; g_autofree guint8 *normal = validity_db_build_cmd_get_prg_status (FALSE, &len); + g_assert_cmpuint (len, ==, 5); g_assert_cmpuint (normal[0], ==, VCSFW_CMD_GET_PRG_STATUS); /* Normal: 00000000 */ diff --git a/tests/test-validity-enroll.c b/tests/test-validity-enroll.c index 68755534..6ed3d9d9 100644 --- a/tests/test-validity-enroll.c +++ b/tests/test-validity-enroll.c @@ -56,6 +56,22 @@ build_block (guint16 tag, const guint8 *payload, guint16 payload_len, return buf; } +/* Wrap raw block data with the 2-byte declared_len prefix the parser expects: + * [declared_len:2LE][blocks...] + * declared_len = blocks_len (total size of all concatenated blocks). */ +static guint8 * +wrap_response (const guint8 *blocks, gsize blocks_len, gsize *out_len) +{ + *out_len = 2 + blocks_len; + + guint8 *buf = g_malloc (*out_len); + + FP_WRITE_UINT16_LE (buf, (guint16) blocks_len); + if (blocks && blocks_len > 0) + memcpy (buf + 2, blocks, blocks_len); + return buf; +} + /* ================================================================ * T8.1: parse empty data — returns TRUE, all fields NULL * ================================================================ */ @@ -65,10 +81,8 @@ test_parse_empty (void) EnrollmentUpdateResult result; gboolean ok = parse_enrollment_update_response (NULL, 0, &result); - g_assert_true (ok); - g_assert_null (result.header); - g_assert_null (result.template_data); - g_assert_null (result.tid); + /* Empty data (len < 2) → parser returns FALSE */ + g_assert_false (ok); } /* ================================================================ @@ -79,11 +93,13 @@ test_parse_template_block (void) { guint8 payload[] = { 0xDE, 0xAD, 0xBE, 0xEF }; gsize block_len; - g_autofree guint8 *data = build_block (0, payload, sizeof (payload), - &block_len); + g_autofree guint8 *block = build_block (0, payload, sizeof (payload), + &block_len); + gsize resp_len; + g_autofree guint8 *data = wrap_response (block, block_len, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, block_len, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); g_assert_nonnull (result.template_data); @@ -102,11 +118,13 @@ test_parse_header_block (void) { guint8 payload[] = { 0x01, 0x02, 0x03 }; gsize block_len; - g_autofree guint8 *data = build_block (1, payload, sizeof (payload), - &block_len); + g_autofree guint8 *block = build_block (1, payload, sizeof (payload), + &block_len); + gsize resp_len; + g_autofree guint8 *data = wrap_response (block, block_len, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, block_len, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); g_assert_nonnull (result.header); @@ -126,11 +144,13 @@ test_parse_tid_block (void) { guint8 payload[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; gsize block_len; - g_autofree guint8 *data = build_block (3, payload, sizeof (payload), - &block_len); + g_autofree guint8 *block = build_block (3, payload, sizeof (payload), + &block_len); + gsize resp_len; + g_autofree guint8 *data = wrap_response (block, block_len, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, block_len, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); g_assert_nonnull (result.tid); @@ -160,15 +180,19 @@ test_parse_multiple_blocks (void) g_autofree guint8 *tid = build_block (3, tid_payload, sizeof (tid_payload), &tid_len); - /* Concatenate all three blocks */ - gsize total = tmpl_len + hdr_len + tid_len; - g_autofree guint8 *data = g_malloc (total); - memcpy (data, tmpl, tmpl_len); - memcpy (data + tmpl_len, hdr, hdr_len); - memcpy (data + tmpl_len + hdr_len, tid, tid_len); + /* Concatenate all three blocks, then wrap with length prefix */ + gsize blocks_total = tmpl_len + hdr_len + tid_len; + g_autofree guint8 *blocks = g_malloc (blocks_total); + + memcpy (blocks, tmpl, tmpl_len); + memcpy (blocks + tmpl_len, hdr, hdr_len); + memcpy (blocks + tmpl_len + hdr_len, tid, tid_len); + + gsize resp_len; + g_autofree guint8 *data = wrap_response (blocks, blocks_total, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, total, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); g_assert_nonnull (result.template_data); @@ -187,14 +211,21 @@ test_parse_multiple_blocks (void) static void test_parse_truncated (void) { - guint8 payload[] = { 0xAA }; - gsize block_len; - g_autofree guint8 *data = build_block (0, payload, sizeof (payload), - &block_len); + /* Build a response where the declared length is consistent with data_len + * but the block content is too short for a full block to be parsed. + * declared_len = 6, so data = [06 00][tag:2][len:2][2 more bytes] + * The block_size = MAGIC_LEN + len will exceed 8 for any len > 0, + * so the parser's "pos + block_size > data_len" check will skip it. */ + guint8 data[8]; + + FP_WRITE_UINT16_LE (data, 6); /* declared_len = 6 */ + FP_WRITE_UINT16_LE (data + 2, 0); /* tag = 0 (template) */ + FP_WRITE_UINT16_LE (data + 4, 10); /* len = 10 → block_size = MAGIC_LEN + 10 > 8 */ + data[6] = 0; + data[7] = 0; - /* Pass data_len shorter than block_size so the block can't be read */ EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, 10, &result); + gboolean ok = parse_enrollment_update_response (data, sizeof (data), &result); g_assert_true (ok); /* No fields should be populated since the block was truncated */ @@ -211,11 +242,13 @@ test_parse_unknown_tag (void) { guint8 payload[] = { 0x99 }; gsize block_len; - g_autofree guint8 *data = build_block (42, payload, sizeof (payload), - &block_len); + g_autofree guint8 *block = build_block (42, payload, sizeof (payload), + &block_len); + gsize resp_len; + g_autofree guint8 *data = wrap_response (block, block_len, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, block_len, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); g_assert_null (result.template_data); @@ -230,6 +263,7 @@ static void test_result_clear (void) { EnrollmentUpdateResult result; + result.header = g_malloc (10); result.header_len = 10; result.template_data = g_malloc (20); @@ -254,10 +288,12 @@ static void test_parse_zero_length_payload (void) { gsize block_len; - g_autofree guint8 *data = build_block (1, NULL, 0, &block_len); + g_autofree guint8 *block = build_block (1, NULL, 0, &block_len); + gsize resp_len; + g_autofree guint8 *data = wrap_response (block, block_len, &resp_len); EnrollmentUpdateResult result; - gboolean ok = parse_enrollment_update_response (data, block_len, &result); + gboolean ok = parse_enrollment_update_response (data, resp_len, &result); g_assert_true (ok); /* Tag 1 with len=0: header should be NULL (len > 0 check in parser) */ @@ -270,23 +306,23 @@ main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); g_test_add_func ("/validity/enroll/parse-empty", - test_parse_empty); + test_parse_empty); g_test_add_func ("/validity/enroll/parse-template-block", - test_parse_template_block); + test_parse_template_block); g_test_add_func ("/validity/enroll/parse-header-block", - test_parse_header_block); + test_parse_header_block); g_test_add_func ("/validity/enroll/parse-tid-block", - test_parse_tid_block); + test_parse_tid_block); g_test_add_func ("/validity/enroll/parse-multiple-blocks", - test_parse_multiple_blocks); + test_parse_multiple_blocks); g_test_add_func ("/validity/enroll/parse-truncated", - test_parse_truncated); + test_parse_truncated); g_test_add_func ("/validity/enroll/parse-unknown-tag", - test_parse_unknown_tag); + test_parse_unknown_tag); g_test_add_func ("/validity/enroll/result-clear", - test_result_clear); + test_result_clear); g_test_add_func ("/validity/enroll/parse-zero-length-payload", - test_parse_zero_length_payload); + test_parse_zero_length_payload); return g_test_run (); } diff --git a/tests/test-validity-fwext.c b/tests/test-validity-fwext.c index 12d8bcf4..5a19262b 100644 --- a/tests/test-validity-fwext.c +++ b/tests/test-validity-fwext.c @@ -152,7 +152,7 @@ test_fw_info_parse_truncated (void) static void test_xpfwext_file_parse (void) { - g_autoptr (GError) error = NULL; + g_autoptr(GError) error = NULL; ValidityFwextFile fwext; gchar *tmpdir; g_autofree gchar *path = NULL; @@ -218,7 +218,7 @@ test_xpfwext_file_parse (void) static void test_xpfwext_file_no_delimiter (void) { - g_autoptr (GError) error = NULL; + g_autoptr(GError) error = NULL; ValidityFwextFile fwext; gchar *tmpdir; g_autofree gchar *path = NULL; @@ -254,7 +254,7 @@ test_xpfwext_file_no_delimiter (void) static void test_xpfwext_file_too_short (void) { - g_autoptr (GError) error = NULL; + g_autoptr(GError) error = NULL; ValidityFwextFile fwext; gchar *tmpdir; g_autofree gchar *path = NULL; @@ -441,7 +441,8 @@ test_hw_reg_read_parse (void) guint8 data[] = { 0x02, 0x00, 0x00, 0x00 }; gboolean ok = validity_fwext_parse_read_hw_reg32 (data, sizeof (data), - &value); + &value); + g_assert_true (ok); g_assert_cmpuint (value, ==, 2); @@ -486,7 +487,7 @@ test_firmware_filename (void) static void test_missing_firmware_file (void) { - g_autoptr (GError) error = NULL; + g_autoptr(GError) error = NULL; /* This should fail since firmware files aren't installed in CI */ g_autofree gchar *path = validity_fwext_find_firmware (0x06cb, 0x009a, @@ -515,7 +516,7 @@ test_missing_firmware_file (void) static void test_unsupported_pid_firmware (void) { - g_autoptr (GError) error = NULL; + g_autoptr(GError) error = NULL; g_autofree gchar *path = validity_fwext_find_firmware (0x1234, 0x5678, &error); @@ -591,53 +592,53 @@ main (int argc, /* Firmware info parsing */ g_test_add_func ("/validity/fwext/fw-info/parse-present", - test_fw_info_parse_present); + test_fw_info_parse_present); g_test_add_func ("/validity/fwext/fw-info/parse-absent", - test_fw_info_parse_absent); + test_fw_info_parse_absent); g_test_add_func ("/validity/fwext/fw-info/parse-unknown-status", - test_fw_info_parse_unknown_status); + test_fw_info_parse_unknown_status); g_test_add_func ("/validity/fwext/fw-info/parse-truncated", - test_fw_info_parse_truncated); + test_fw_info_parse_truncated); /* File parsing */ g_test_add_func ("/validity/fwext/file/parse", - test_xpfwext_file_parse); + test_xpfwext_file_parse); g_test_add_func ("/validity/fwext/file/no-delimiter", - test_xpfwext_file_no_delimiter); + test_xpfwext_file_no_delimiter); g_test_add_func ("/validity/fwext/file/too-short", - test_xpfwext_file_too_short); + test_xpfwext_file_too_short); g_test_add_func ("/validity/fwext/file/clear-idempotent", - test_file_clear_idempotent); + test_file_clear_idempotent); /* Command format */ g_test_add_func ("/validity/fwext/cmd/write-flash", - test_flash_write_cmd_format); + test_flash_write_cmd_format); g_test_add_func ("/validity/fwext/cmd/write-fw-sig", - test_fw_sig_cmd_format); + test_fw_sig_cmd_format); g_test_add_func ("/validity/fwext/cmd/write-hw-reg", - test_hw_reg_write_cmd_format); + test_hw_reg_write_cmd_format); g_test_add_func ("/validity/fwext/cmd/read-hw-reg", - test_hw_reg_read_cmd_format); + test_hw_reg_read_cmd_format); g_test_add_func ("/validity/fwext/cmd/read-hw-reg-parse", - test_hw_reg_read_parse); + test_hw_reg_read_parse); g_test_add_func ("/validity/fwext/cmd/reboot", - test_reboot_cmd_format); + test_reboot_cmd_format); /* Chunk iteration */ g_test_add_func ("/validity/fwext/chunk-iteration", - test_chunk_iteration); + test_chunk_iteration); /* Firmware filename mapping */ g_test_add_func ("/validity/fwext/firmware-name", - test_firmware_filename); + test_firmware_filename); g_test_add_func ("/validity/fwext/find-firmware/missing", - test_missing_firmware_file); + test_missing_firmware_file); g_test_add_func ("/validity/fwext/find-firmware/unsupported-pid", - test_unsupported_pid_firmware); + test_unsupported_pid_firmware); /* Blob lookup */ g_test_add_func ("/validity/fwext/db-write-enable", - test_db_write_enable_blob); + test_db_write_enable_blob); return g_test_run (); } diff --git a/tests/test-validity-hal.c b/tests/test-validity-hal.c index 1150d09e..b05078e6 100644 --- a/tests/test-validity-hal.c +++ b/tests/test-validity-hal.c @@ -40,7 +40,9 @@ static void test_hal_lookup_by_pid (void) { /* All 4 supported devices */ - struct { guint16 vid; guint16 pid; } devices[] = { + struct { guint16 vid; + guint16 pid; + } devices[] = { { 0x138a, 0x0090 }, { 0x138a, 0x0097 }, { 0x06cb, 0x009a }, @@ -64,6 +66,7 @@ static void test_hal_lookup_invalid (void) { const ValidityDeviceDesc *desc = validity_hal_device_lookup (99); + g_assert_null (desc); } @@ -75,6 +78,7 @@ test_hal_lookup_by_pid_invalid (void) { const ValidityDeviceDesc *desc = validity_hal_device_lookup_by_pid (0x1234, 0x5678); + g_assert_null (desc); } @@ -113,6 +117,7 @@ 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 */ @@ -190,6 +195,7 @@ 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 */ @@ -218,6 +224,7 @@ test_hal_lookup_consistency (void) 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); } @@ -227,25 +234,25 @@ 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); + test_hal_lookup_all_types); g_test_add_func ("/validity/hal/lookup-by-pid", - test_hal_lookup_by_pid); + test_hal_lookup_by_pid); g_test_add_func ("/validity/hal/lookup-invalid", - test_hal_lookup_invalid); + test_hal_lookup_invalid); g_test_add_func ("/validity/hal/lookup-by-pid-invalid", - test_hal_lookup_by_pid_invalid); + test_hal_lookup_by_pid_invalid); g_test_add_func ("/validity/hal/blobs-present", - test_hal_blobs_present); + test_hal_blobs_present); g_test_add_func ("/validity/hal/pid-0090-specifics", - test_hal_pid_0090_specifics); + test_hal_pid_0090_specifics); g_test_add_func ("/validity/hal/clean-slate-present", - test_hal_clean_slate_present); + test_hal_clean_slate_present); g_test_add_func ("/validity/hal/flash-layout", - test_hal_flash_layout); + test_hal_flash_layout); g_test_add_func ("/validity/hal/blob-sizes", - test_hal_blob_sizes); + test_hal_blob_sizes); g_test_add_func ("/validity/hal/lookup-consistency", - test_hal_lookup_consistency); + test_hal_lookup_consistency); return g_test_run (); } diff --git a/tests/test-validity-pair.c b/tests/test-validity-pair.c index 84e7aa3a..6ceba067 100644 --- a/tests/test-validity-pair.c +++ b/tests/test-validity-pair.c @@ -34,6 +34,7 @@ test_parse_flash_info_valid (void) * [jid0:2LE][jid1:2LE][blocks:2LE][unknown0:2LE][blocksize:2LE] * [unknown1:2LE][pcnt:2LE] = 14 bytes minimum */ guint8 data[14]; + memset (data, 0, sizeof (data)); /* jid0=0x01, jid1=0x02, blocks=0x1000, unknown0=0, blocksize=0x100, @@ -65,6 +66,7 @@ static void test_parse_flash_info_needs_pairing (void) { guint8 data[14]; + memset (data, 0, sizeof (data)); FP_WRITE_UINT16_LE (data + 0, 0x0001); @@ -89,6 +91,7 @@ static void test_parse_flash_info_too_short (void) { guint8 data[10]; /* less than 14 bytes */ + memset (data, 0, sizeof (data)); ValidityFlashIcParams ic; @@ -114,6 +117,7 @@ test_serialize_partition (void) }; guint8 out[VALIDITY_PARTITION_ENTRY_SIZE]; + validity_pair_serialize_partition (&part, out); /* Check first 12 bytes: id(1) type(1) access_lvl(2LE) offset(4LE) size(4LE) */ @@ -147,6 +151,7 @@ static void test_make_cert_size (void) { guint8 pub_x[32], pub_y[32]; + RAND_bytes (pub_x, 32); RAND_bytes (pub_y, 32); @@ -205,8 +210,8 @@ test_encrypt_key_structure (void) gsize blob_len; g_autofree guint8 *blob = validity_pair_encrypt_key (priv, pub_x, pub_y, - enc_key, val_key, - &blob_len); + enc_key, val_key, + &blob_len); g_assert_nonnull (blob); /* Blob format: 0x02(1) + IV(16) + ciphertext(112) + HMAC(32) = 161 */ @@ -231,8 +236,8 @@ test_encrypt_key_hmac_valid (void) gsize blob_len; g_autofree guint8 *blob = validity_pair_encrypt_key (priv, pub_x, pub_y, - enc_key, val_key, - &blob_len); + enc_key, val_key, + &blob_len); g_assert_nonnull (blob); g_assert_cmpuint (blob_len, ==, 161); @@ -260,6 +265,7 @@ test_build_partition_flash_cmd (void) /* Use a real device descriptor for the flash layout */ const ValidityDeviceDesc *desc = validity_hal_device_lookup (VALIDITY_DEV_9A); + g_assert_nonnull (desc); ValidityFlashIcParams flash_ic = { @@ -295,6 +301,7 @@ static void test_build_tls_flash_size (void) { ValidityPairState state; + validity_pair_state_init (&state); /* Set up minimal test data */ @@ -344,6 +351,7 @@ static void test_build_tls_flash_blocks (void) { ValidityPairState state; + validity_pair_state_init (&state); guint8 priv_blob[50]; @@ -388,6 +396,7 @@ static void test_pair_state_lifecycle (void) { ValidityPairState state; + validity_pair_state_init (&state); g_assert_null (state.client_key); @@ -408,6 +417,7 @@ static void test_pair_state_free_with_resources (void) { ValidityPairState state; + validity_pair_state_init (&state); state.server_cert = g_malloc (100); @@ -447,9 +457,9 @@ test_encrypt_key_different_inputs (void) gsize len1, len2; g_autofree guint8 *blob1 = validity_pair_encrypt_key (priv1, pub_x, pub_y, - enc_key, val_key, &len1); + enc_key, val_key, &len1); g_autofree guint8 *blob2 = validity_pair_encrypt_key (priv2, pub_x, pub_y, - enc_key, val_key, &len2); + enc_key, val_key, &len2); g_assert_nonnull (blob1); g_assert_nonnull (blob2); @@ -465,33 +475,33 @@ main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); g_test_add_func ("/validity/pair/parse-flash-info-valid", - test_parse_flash_info_valid); + test_parse_flash_info_valid); g_test_add_func ("/validity/pair/parse-flash-info-needs-pairing", - test_parse_flash_info_needs_pairing); + test_parse_flash_info_needs_pairing); g_test_add_func ("/validity/pair/parse-flash-info-too-short", - test_parse_flash_info_too_short); + test_parse_flash_info_too_short); g_test_add_func ("/validity/pair/serialize-partition", - test_serialize_partition); + test_serialize_partition); g_test_add_func ("/validity/pair/make-cert-size", - test_make_cert_size); + test_make_cert_size); g_test_add_func ("/validity/pair/make-cert-deterministic", - test_make_cert_deterministic); + test_make_cert_deterministic); g_test_add_func ("/validity/pair/encrypt-key-structure", - test_encrypt_key_structure); + test_encrypt_key_structure); g_test_add_func ("/validity/pair/encrypt-key-hmac-valid", - test_encrypt_key_hmac_valid); + test_encrypt_key_hmac_valid); g_test_add_func ("/validity/pair/build-partition-flash-cmd", - test_build_partition_flash_cmd); + test_build_partition_flash_cmd); g_test_add_func ("/validity/pair/build-tls-flash-size", - test_build_tls_flash_size); + test_build_tls_flash_size); g_test_add_func ("/validity/pair/build-tls-flash-blocks", - test_build_tls_flash_blocks); + test_build_tls_flash_blocks); g_test_add_func ("/validity/pair/state-lifecycle", - test_pair_state_lifecycle); + test_pair_state_lifecycle); g_test_add_func ("/validity/pair/state-free-with-resources", - test_pair_state_free_with_resources); + test_pair_state_free_with_resources); g_test_add_func ("/validity/pair/encrypt-key-different-inputs", - test_encrypt_key_different_inputs); + test_encrypt_key_different_inputs); return g_test_run (); } diff --git a/tests/test-validity-sensor.c b/tests/test-validity-sensor.c index 2a308ff7..e33ffe7d 100644 --- a/tests/test-validity-sensor.c +++ b/tests/test-validity-sensor.c @@ -32,6 +32,7 @@ test_identify_sensor_parse (void) /* Build synthetic response: zeroes=0, version=0x13, major=0x004a */ guint8 data[8]; + FP_WRITE_UINT32_LE (&data[0], 0); /* zeroes */ FP_WRITE_UINT16_LE (&data[4], 0x0013); /* version */ FP_WRITE_UINT16_LE (&data[6], 0x004a); /* major */ @@ -245,6 +246,7 @@ test_identify_then_lookup (void) /* Simulate cmd 0x75 response for T480s: major=0x004a, version=0x13 */ guint8 data[8]; + FP_WRITE_UINT32_LE (&data[0], 0); FP_WRITE_UINT16_LE (&data[4], 0x0013); FP_WRITE_UINT16_LE (&data[6], 0x004a); @@ -315,33 +317,33 @@ main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); g_test_add_func ("/validity/sensor/identify/parse", - test_identify_sensor_parse); + test_identify_sensor_parse); g_test_add_func ("/validity/sensor/identify/truncated", - test_identify_sensor_parse_truncated); + test_identify_sensor_parse_truncated); g_test_add_func ("/validity/sensor/devinfo/lookup_exact", - test_device_info_lookup_exact); + test_device_info_lookup_exact); g_test_add_func ("/validity/sensor/devinfo/lookup_another", - test_device_info_lookup_another); + test_device_info_lookup_another); g_test_add_func ("/validity/sensor/devinfo/lookup_unknown", - test_device_info_lookup_unknown); + test_device_info_lookup_unknown); g_test_add_func ("/validity/sensor/devinfo/lookup_fuzzy", - test_device_info_lookup_fuzzy); + test_device_info_lookup_fuzzy); g_test_add_func ("/validity/sensor/typeinfo/lookup", - test_sensor_type_info_lookup); + test_sensor_type_info_lookup); g_test_add_func ("/validity/sensor/typeinfo/lookup_db", - test_sensor_type_info_lookup_db); + test_sensor_type_info_lookup_db); g_test_add_func ("/validity/sensor/typeinfo/lookup_unknown", - test_sensor_type_info_lookup_unknown); + test_sensor_type_info_lookup_unknown); g_test_add_func ("/validity/sensor/factory_bits/cmd_format", - test_factory_bits_cmd_format); + test_factory_bits_cmd_format); g_test_add_func ("/validity/sensor/factory_bits/buffer_too_small", - test_factory_bits_cmd_buffer_too_small); + test_factory_bits_cmd_buffer_too_small); g_test_add_func ("/validity/sensor/identify_then_lookup", - test_identify_then_lookup); + test_identify_then_lookup); g_test_add_func ("/validity/sensor/state_lifecycle", - test_sensor_state_lifecycle); + test_sensor_state_lifecycle); g_test_add_func ("/validity/sensor/calibration_blob_present", - test_calibration_blob_present); + test_calibration_blob_present); return g_test_run (); } diff --git a/tests/test-validity-tls.c b/tests/test-validity-tls.c index 8fda74ea..10eadbd8 100644 --- a/tests/test-validity-tls.c +++ b/tests/test-validity-tls.c @@ -101,6 +101,7 @@ static void test_encrypt_decrypt_roundtrip (void) { ValidityTlsState tls; + validity_tls_init (&tls); /* Set up encryption/decryption keys (same for roundtrip test) */ @@ -135,6 +136,7 @@ static void test_encrypt_block_aligned (void) { ValidityTlsState tls; + validity_tls_init (&tls); memset (tls.encryption_key, 0x55, TLS_AES_KEY_SIZE); @@ -171,6 +173,7 @@ static void test_decrypt_invalid (void) { ValidityTlsState tls; + validity_tls_init (&tls); memset (tls.decryption_key, 0x55, TLS_AES_KEY_SIZE); @@ -198,6 +201,7 @@ static void test_psk_derivation (void) { ValidityTlsState tls; + validity_tls_init (&tls); validity_tls_derive_psk (&tls); @@ -235,6 +239,7 @@ static void test_psk_deterministic (void) { ValidityTlsState tls1, tls2; + validity_tls_init (&tls1); validity_tls_init (&tls2); @@ -257,6 +262,7 @@ static void test_flash_parse_empty (void) { ValidityTlsState tls; + validity_tls_init (&tls); GError *error = NULL; @@ -281,6 +287,7 @@ static void test_flash_parse_truncated (void) { ValidityTlsState tls; + validity_tls_init (&tls); GError *error = NULL; @@ -319,6 +326,7 @@ static void test_build_client_hello (void) { ValidityTlsState tls; + validity_tls_init (&tls); gsize out_len; @@ -361,6 +369,7 @@ static void test_unwrap_invalid (void) { ValidityTlsState tls; + validity_tls_init (&tls); GError *error = NULL; @@ -369,8 +378,8 @@ test_unwrap_invalid (void) /* Short data → truncated record header */ guint8 short_data[] = { 0x17, 0x03 }; guint8 *result = validity_tls_unwrap_response (&tls, short_data, - sizeof (short_data), - &out_len, &error); + sizeof (short_data), + &out_len, &error); g_assert_null (result); g_assert_nonnull (error); g_clear_error (&error); @@ -380,8 +389,8 @@ test_unwrap_invalid (void) 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; result = validity_tls_unwrap_response (&tls, app_early, - sizeof (app_early), - &out_len, &error); + sizeof (app_early), + &out_len, &error); g_assert_null (result); g_assert_nonnull (error); g_clear_error (&error); @@ -401,6 +410,7 @@ static void test_flash_parse_needs_psk (void) { ValidityTlsState tls_with_psk, tls_no_psk; + validity_tls_init (&tls_with_psk); validity_tls_init (&tls_no_psk); @@ -565,6 +575,7 @@ test_flash_response_header (void) /* Wrap it in the response header format: [size:4 LE][unk:2][data] */ guint32 data_size = sizeof (flash_data); guint8 response[6 + sizeof (flash_data)]; + FP_WRITE_UINT32_LE (response, data_size); response[4] = 0x00; /* unknown byte 1 */ response[5] = 0x00; /* unknown byte 2 */ @@ -635,6 +646,7 @@ test_server_hello_rejects_vcsfw_prefix (void) /* Wrap in TLS record: content_type(1) + version(2) + length(2) + body */ gsize raw_tls_len = 5 + hs_len; guint8 *raw_tls = g_malloc (raw_tls_len); + raw_tls[0] = TLS_CONTENT_HANDSHAKE; /* 0x16 */ raw_tls[1] = TLS_VERSION_MAJOR; raw_tls[2] = TLS_VERSION_MINOR; @@ -649,7 +661,7 @@ test_server_hello_rejects_vcsfw_prefix (void) GError *error = NULL; gboolean result = validity_tls_parse_server_hello (&tls, raw_tls, - raw_tls_len, &error); + raw_tls_len, &error); g_assert_no_error (error); g_assert_true (result); /* Verify server_random was properly extracted */ @@ -703,6 +715,7 @@ static void test_client_hello_tls_prefix (void) { ValidityTlsState tls; + validity_tls_init (&tls); gsize out_len; diff --git a/tests/test-validity-verify.c b/tests/test-validity-verify.c index fb638cc9..01bc3294 100644 --- a/tests/test-validity-verify.c +++ b/tests/test-validity-verify.c @@ -52,11 +52,11 @@ build_tlv_entry (guint8 *buf, guint16 tag, const guint8 *data, guint16 len) * total_len(2LE) | TLV entries... * ================================================================ */ static guint8 * -build_match_payload (guint32 user_dbid, - guint16 subtype, +build_match_payload (guint32 user_dbid, + guint16 subtype, const guint8 *hash, - gsize hash_len, - gsize *out_len) + gsize hash_len, + gsize *out_len) { /* Max size: 2 (total_len) + 3 entries × (4 header + max data) */ guint8 *buf = g_new0 (guint8, 256); @@ -64,6 +64,7 @@ build_match_payload (guint32 user_dbid, /* Tag 1: user_dbid (4 bytes LE) */ guint8 dbid_data[4]; + FP_WRITE_UINT32_LE (dbid_data, user_dbid); pos += build_tlv_entry (&buf[pos], 1, dbid_data, 4); @@ -128,6 +129,7 @@ test_parse_match_result_multi_tags (void) /* Tag 3 first: subtype = 7 */ guint8 sub[2]; + FP_WRITE_UINT16_LE (sub, 7); pos += build_tlv_entry (&buf[pos], 3, sub, 2); @@ -188,6 +190,7 @@ test_parse_match_result_truncated (void) /* Only 1 byte — too short for total_len */ guint8 buf1[1] = { 0x05 }; ValidityMatchResult result = { 0 }; + g_assert_false (validity_parse_match_result (buf1, 1, &result)); /* total_len says 20 but only 6 bytes follow (partial TLV entry) */ @@ -218,6 +221,7 @@ test_parse_match_result_unknown_tags (void) /* Unknown tag 99 with 2 bytes of data */ guint8 unk[] = { 0x42, 0x43 }; + pos += build_tlv_entry (&buf[pos], 99, unk, 2); /* Tag 1: user_dbid = 0x0042 */ @@ -481,6 +485,7 @@ static void test_match_result_clear (void) { ValidityMatchResult result = { 0 }; + result.matched = TRUE; result.user_dbid = 42; result.subtype = 5; @@ -503,49 +508,49 @@ main (int argc, char *argv[]) /* R1: parse_match_result regression tests (Issue #1: dead while loop) */ g_test_add_func ("/validity/verify/parse_match_result_valid", - test_parse_match_result_valid); + test_parse_match_result_valid); g_test_add_func ("/validity/verify/parse_match_result_multi_tags", - test_parse_match_result_multi_tags); + test_parse_match_result_multi_tags); g_test_add_func ("/validity/verify/parse_match_result_empty", - test_parse_match_result_empty); + test_parse_match_result_empty); g_test_add_func ("/validity/verify/parse_match_result_truncated", - test_parse_match_result_truncated); + test_parse_match_result_truncated); g_test_add_func ("/validity/verify/parse_match_result_unknown_tags", - test_parse_match_result_unknown_tags); + test_parse_match_result_unknown_tags); g_test_add_func ("/validity/verify/match_result_clear", - test_match_result_clear); + test_match_result_clear); /* R2: identity builder NULL regression (Issue #2: NULL crash) */ g_test_add_func ("/validity/verify/build_identity_null", - test_build_identity_null); + test_build_identity_null); g_test_add_func ("/validity/verify/build_identity_valid_uuid", - test_build_identity_valid_uuid); + test_build_identity_valid_uuid); /* R3: gallery matching by subtype (Issue #3: always returned first) */ g_test_add_func ("/validity/verify/gallery_match_by_subtype", - test_gallery_match_by_subtype); + test_gallery_match_by_subtype); g_test_add_func ("/validity/verify/gallery_match_fallback", - test_gallery_match_fallback); + test_gallery_match_fallback); g_test_add_func ("/validity/verify/gallery_match_empty", - test_gallery_match_empty); + test_gallery_match_empty); /* R4: struct field separation (Issue #4: field abuse) */ g_test_add_func ("/validity/verify/struct_separate_fields", - test_struct_separate_fields); + test_struct_separate_fields); /* R5: del_record command format (Issue #5: delete SSM non-functional) */ g_test_add_func ("/validity/verify/del_record_format", - test_del_record_format); + test_del_record_format); /* R6: match_finger single allocation (Issue #6: double alloc) */ g_test_add_func ("/validity/verify/match_finger_size", - test_match_finger_size); + test_match_finger_size); /* R7: clear/delete storage SSM states (Issue #7: stub) */ g_test_add_func ("/validity/verify/clear_storage_states", - test_clear_storage_states_exist); + test_clear_storage_states_exist); g_test_add_func ("/validity/verify/delete_states", - test_delete_states_exist); + test_delete_states_exist); return g_test_run (); }