From dac614571c9ca2d548330a970851e5d2d417ab0f Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 6 Dec 2024 17:18:27 +0100 Subject: [PATCH] testing upload --- libfprint/drivers/crfpmoc/crfpmoc.c | 92 ++++++++++++++++++++++++++++- libfprint/drivers/crfpmoc/crfpmoc.h | 24 ++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/crfpmoc/crfpmoc.c b/libfprint/drivers/crfpmoc/crfpmoc.c index d7504746..b5b3fc9d 100644 --- a/libfprint/drivers/crfpmoc/crfpmoc.c +++ b/libfprint/drivers/crfpmoc/crfpmoc.c @@ -497,6 +497,21 @@ crfpmoc_ec_max_insize(FpiDeviceCrfpMoc *self, guint32 *max_insize, GError **erro return TRUE; } +static gboolean +crfpmoc_ec_max_outsize(FpiDeviceCrfpMoc *self, guint32 *max_outsize, GError **error) +{ + struct crfpmoc_ec_response_get_protocol_info protocol_info; + gboolean rv; + + rv = crfpmoc_ec_command(self, CRFPMOC_EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, &protocol_info, sizeof(protocol_info), error); + if (!rv) + return rv; + + *max_outsize = protocol_info.max_request_packet_size - sizeof(struct crfpmoc_ec_host_request); + + return TRUE; +} + static gboolean crfpmoc_fp_download_frame (FpiDeviceCrfpMoc *self, struct crfpmoc_ec_response_fp_info *info, @@ -550,7 +565,7 @@ crfpmoc_fp_download_frame (FpiDeviceCrfpMoc *self, num_attempts++; rv = crfpmoc_ec_command(self, CRFPMOC_EC_CMD_FP_FRAME, 0, &p, sizeof(p), ptr, stride, error); if (rv) { - break; // Success + break; } if (g_error_matches(*error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) { fp_dbg("Access denied, stopping retrying"); @@ -573,6 +588,78 @@ crfpmoc_fp_download_frame (FpiDeviceCrfpMoc *self, return TRUE; } +static gboolean +crfpmoc_fp_upload_template (FpiDeviceCrfpMoc *self, + const guint8 *template_data, + gsize template_size, + GError **error) +{ + struct crfpmoc_ec_params_fp_template *p = NULL; + guint32 offset = 0; + guint32 tlen; + gboolean rv = FALSE; + guint32 ec_max_outsize = 0; + guint32 max_chunk = 0; + gsize struct_size; + + rv = crfpmoc_ec_max_outsize(self, &ec_max_outsize, error); + if (!rv) { + g_prefix_error(error, "Failed to get max outsize: "); + return FALSE; + } + + max_chunk = ec_max_outsize - offsetof(struct crfpmoc_ec_params_fp_template, data) - 4; + + + while (template_size > 0) { + tlen = MIN(max_chunk, template_size); + + struct_size = offsetof(struct crfpmoc_ec_params_fp_template, data) + tlen; + p = g_malloc0(struct_size); + + if (!p) { + g_set_error(error, + G_IO_ERROR, + G_DBUS_ERROR_NO_MEMORY, + "Failed to allocate memory for template upload."); + return FALSE; + } + + p->offset = offset; + p->size = tlen; + + template_size -= tlen; + + if (!template_size) { + p->size |= CRFPMOC_FP_TEMPLATE_COMMIT; + } + + + memcpy(p->data, template_data + offset, tlen); + + rv = crfpmoc_ec_command(self, + CRFPMOC_EC_CMD_FP_TEMPLATE, + 0, + p, + offsetof(struct crfpmoc_ec_params_fp_template, data) + tlen, + NULL, + 0, + error); + + g_free(p); + p = NULL; + + if (!rv) { + g_prefix_error(error, "Failed to upload template chunk at offset %u: ", offset); + return FALSE; + } + + offset += tlen; + } + + return TRUE; +} + static void crfpmoc_cmd_wait_event_fingerprint (FpiDeviceCrfpMoc *self) @@ -836,8 +923,7 @@ crfpmoc_verify_run_state (FpiSsm *ssm, FpDevice *device) size_t frame_size; crfpmoc_get_print_data(test, &frame, &frame_size); - // upload the frame to the device - + crfpmoc_fp_upload_template(self, frame, frame_size, &error); diff --git a/libfprint/drivers/crfpmoc/crfpmoc.h b/libfprint/drivers/crfpmoc/crfpmoc.h index 6f15b9c9..eaf881b9 100644 --- a/libfprint/drivers/crfpmoc/crfpmoc.h +++ b/libfprint/drivers/crfpmoc/crfpmoc.h @@ -99,6 +99,20 @@ struct crfpmoc_ec_params_fp_frame { guint32 size; } __attribute__((packed)); +/* Load a template into the MCU */ +#define CRFPMOC_EC_CMD_FP_TEMPLATE 0x0405 +/* Flag in the 'size' field indicating that the full template has been sent */ +#define CRFPMOC_FP_TEMPLATE_COMMIT 0x80000000 + + +struct crfpmoc_ec_params_fp_template { + guint32 offset; + guint32 size; + guint8 data[]; +} __attribute__((packed)); + + + #define CRFPMOC_EC_CMD_GET_PROTOCOL_INFO 0x000B struct crfpmoc_ec_response_get_protocol_info { /* Fields which exist if at least protocol version 3 supported */ @@ -108,6 +122,7 @@ struct crfpmoc_ec_response_get_protocol_info { guint32 flags; } __attribute__((packed)); +// crfpmoc_ec_host_response and crfpmoc_ec_host_request are only here for the size of the struct struct crfpmoc_ec_host_response { guint8 struct_version; guint8 checksum; @@ -116,6 +131,15 @@ struct crfpmoc_ec_host_response { guint16 reserved; } __attribute__((packed)); +struct crfpmoc_ec_host_request { + guint8 struct_version; + guint8 checksum; + guint16 command; + guint8 command_version; + guint8 reserved; + guint16 data_len; +} __attribute__((packed)); + #define CRFPMOC_EC_CMD_FP_ENC_STATUS 0x0409 /* FP TPM seed has been set or not */