diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eae6ca8..5c99b05 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ image: $FEDORA_IMAGE .build_one_driver_template: &build_one_driver script: - # Build with a driver that doesn't need imaging, or nss + # Build with a driver that doesn't need imaging, or openssl - meson setup _build --werror -Ddrivers=$driver - meson compile -C _build - rm -rf _build/ diff --git a/.gitlab-ci/libfprint-image-variables.yaml b/.gitlab-ci/libfprint-image-variables.yaml index e568839..786c93a 100644 --- a/.gitlab-ci/libfprint-image-variables.yaml +++ b/.gitlab-ci/libfprint-image-variables.yaml @@ -1,2 +1,2 @@ variables: - LIBFPRINT_IMAGE_TAG: v3 + LIBFPRINT_IMAGE_TAG: v4 diff --git a/.gitlab-ci/libfprint-templates.yaml b/.gitlab-ci/libfprint-templates.yaml index 9c8de1c..f5ec962 100644 --- a/.gitlab-ci/libfprint-templates.yaml +++ b/.gitlab-ci/libfprint-templates.yaml @@ -22,7 +22,7 @@ libX11-devel libXv-devel meson - nss-devel + openssl-devel pixman-devel python3-cairo python3-gobject @@ -40,7 +40,7 @@ glibc \ libgusb \ libusb \ - nss \ + openssl \ pixman git clone https://github.com/martinpitt/umockdev.git && \ diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 047e64c..b9017e6 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -20,8 +20,8 @@ #define FP_COMPONENT "uru4000" -#include -#include +#include +#include #include "drivers_api.h" @@ -148,10 +148,7 @@ struct _FpiDeviceUru4000 int fwfixer_offset; unsigned char fwfixer_value; - CK_MECHANISM_TYPE cipher; - PK11SlotInfo *slot; - PK11SymKey *symkey; - SECItem *param; + EVP_CIPHER_CTX *cipher_ctx; }; G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000, FpImageDevice); @@ -246,13 +243,29 @@ response_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *e fpi_ssm_mark_failed (ssm, error); } +static GError * +openssl_device_error (void) +{ + char buf[256]; + unsigned long e; + + e = ERR_get_error (); + if (e == 0) + return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, + "unexpected OpenSSL error"); + + ERR_error_string_n (e, buf, G_N_ELEMENTS (buf)); + + return fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, "OpenSSL error: %s", + buf); +} + static void challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error) { FpiSsm *ssm = user_data; FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); - unsigned char respdata[CR_LENGTH]; - PK11Context *ctx; + unsigned char respdata[CR_LENGTH * 2]; int outlen; if (error) @@ -261,17 +274,39 @@ challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError * return; } + if (transfer->actual_length != CR_LENGTH) + { + error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Unexpected buffer length (%" G_GSIZE_FORMAT + "instead of %d)", + transfer->actual_length, CR_LENGTH); + fpi_ssm_mark_failed (ssm, g_steal_pointer (&error)); + return; + } + /* submit response */ /* produce response from challenge */ - ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT, - self->symkey, self->param); - if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess || - PK11_Finalize (ctx) != SECSuccess) + if (!EVP_EncryptUpdate (self->cipher_ctx, respdata, &outlen, transfer->buffer, CR_LENGTH)) { - fp_err ("Failed to encrypt challenge data"); - error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data"); + fpi_ssm_mark_failed (ssm, openssl_device_error ()); + return; + } + + if (outlen != CR_LENGTH) + { + error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Unexpected encrypted buffer length (%d" + "instead of %d)", + outlen, CR_LENGTH); + fpi_ssm_mark_failed (ssm, g_steal_pointer (&error)); + return; + } + + if (!EVP_EncryptFinal_ex (self->cipher_ctx, respdata + outlen, &outlen)) + { + fpi_ssm_mark_failed (ssm, openssl_device_error ()); + return; } - PK11_DestroyContext (ctx, PR_TRUE); if (!error) write_regs (FP_IMAGE_DEVICE (dev), REG_RESPONSE, CR_LENGTH, respdata, response_cb, ssm); @@ -1270,8 +1305,6 @@ dev_init (FpImageDevice *dev) g_autoptr(GPtrArray) interfaces = NULL; GUsbInterface *iface = NULL; guint64 driver_data; - SECStatus rv; - SECItem item; int i; interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error); @@ -1343,20 +1376,6 @@ dev_init (FpImageDevice *dev) return; } - /* Disable loading p11-kit's user configuration */ - g_setenv ("P11_KIT_NO_USER_CONFIG", "1", TRUE); - - /* Initialise NSS early */ - rv = NSS_NoDB_Init ("."); - if (rv != SECSuccess) - { - fp_err ("could not initialise NSS"); - fpi_image_device_open_complete (dev, - fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, - "Could not initialise NSS")); - return; - } - self = FPI_DEVICE_URU4000 (dev); g_clear_pointer (&self->rand, g_rand_free); @@ -1369,35 +1388,17 @@ dev_init (FpImageDevice *dev) self->interface = g_usb_interface_get_number (iface); /* Set up encryption */ - self->cipher = CKM_AES_ECB; - self->slot = PK11_GetBestSlot (self->cipher, NULL); - if (self->slot == NULL) + if (!(self->cipher_ctx = EVP_CIPHER_CTX_new ())) { - fp_err ("could not get encryption slot"); - fpi_image_device_open_complete (dev, - fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, - "Could not get encryption slot")); + fpi_image_device_open_complete (dev, openssl_device_error ()); return; } - item.type = siBuffer; - item.data = (unsigned char *) crkey; - item.len = sizeof (crkey); - self->symkey = PK11_ImportSymKey (self->slot, - self->cipher, - PK11_OriginUnwrap, - CKA_ENCRYPT, - &item, NULL); - if (self->symkey == NULL) + + if (!EVP_EncryptInit_ex (self->cipher_ctx, EVP_aes_128_ecb (), NULL, crkey, NULL)) { - fp_err ("failed to import key into NSS"); - PK11_FreeSlot (self->slot); - self->slot = NULL; - fpi_image_device_open_complete (dev, - fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, - "Failed to import key into NSS")); + fpi_image_device_open_complete (dev, openssl_device_error ()); return; } - self->param = PK11_ParamFromIV (self->cipher, NULL); fpi_image_device_open_complete (dev, NULL); } @@ -1408,14 +1409,7 @@ dev_deinit (FpImageDevice *dev) GError *error = NULL; FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev); - if (self->symkey) - PK11_FreeSymKey (self->symkey); - if (self->param) - SECITEM_FreeItem (self->param, PR_TRUE); - if (self->slot) - PK11_FreeSlot (self->slot); - - NSS_Shutdown (); + g_clear_pointer (&self->cipher_ctx, EVP_CIPHER_CTX_free); g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)), self->interface, 0, &error); diff --git a/libfprint/meson.build b/libfprint/meson.build index 2316b14..1bef439 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -162,7 +162,7 @@ helper_sources = { [ 'drivers/aesx660.c' ], 'aes3k' : [ 'drivers/aes3k.c' ], - 'nss' : + 'openssl' : [ ], 'udev' : [ ], diff --git a/meson.build b/meson.build index 19c06ac..b73876f 100644 --- a/meson.build +++ b/meson.build @@ -203,7 +203,7 @@ driver_helper_mapping = { 'aes2660' : [ 'aeslib', 'aesx660' ], 'aes3500' : [ 'aeslib', 'aes3k' ], 'aes4000' : [ 'aeslib', 'aes3k' ], - 'uru4000' : [ 'nss' ], + 'uru4000' : [ 'openssl' ], 'elanspi' : [ 'udev' ], 'virtual_image' : [ 'virtual' ], 'virtual_device' : [ 'virtual' ], @@ -260,13 +260,13 @@ foreach i : driver_helpers libfprint_conf.set10('HAVE_PIXMAN', true) optional_deps += imaging_dep - elif i == 'nss' - nss_dep = dependency('nss', required: false) - if not nss_dep.found() - error('nss is required for @0@ and possibly others'.format(driver)) + elif i == 'openssl' + openssl_dep = dependency('openssl', version: '>= 3.0', required: false) + if not openssl_dep.found() + error('OpenSSL is required for @0@ and possibly others'.format(driver)) endif - optional_deps += nss_dep + optional_deps += openssl_dep elif i == 'udev' install_udev_rules = true