mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
uru4000: Use OpenSSL to perform AES-ECB encryption
Drop usage of NSS library now that openssl >= 3.0 has not anymore any license incompatibility. OpenSSL will provide us a better ground for further developments and it's also the preferred crypto library by most distros these days
This commit is contained in:
committed by
Marco Trevisan
parent
7a60912b61
commit
133eaab061
@@ -43,7 +43,7 @@ image: $FEDORA_IMAGE
|
|||||||
|
|
||||||
.build_one_driver_template: &build_one_driver
|
.build_one_driver_template: &build_one_driver
|
||||||
script:
|
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 setup _build --werror -Ddrivers=$driver
|
||||||
- meson compile -C _build
|
- meson compile -C _build
|
||||||
- rm -rf _build/
|
- rm -rf _build/
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
variables:
|
variables:
|
||||||
LIBFPRINT_IMAGE_TAG: v3
|
LIBFPRINT_IMAGE_TAG: v4
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
libX11-devel
|
libX11-devel
|
||||||
libXv-devel
|
libXv-devel
|
||||||
meson
|
meson
|
||||||
nss-devel
|
openssl-devel
|
||||||
pixman-devel
|
pixman-devel
|
||||||
python3-cairo
|
python3-cairo
|
||||||
python3-gobject
|
python3-gobject
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
glibc \
|
glibc \
|
||||||
libgusb \
|
libgusb \
|
||||||
libusb \
|
libusb \
|
||||||
nss \
|
openssl \
|
||||||
pixman
|
pixman
|
||||||
|
|
||||||
git clone https://github.com/martinpitt/umockdev.git && \
|
git clone https://github.com/martinpitt/umockdev.git && \
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
#define FP_COMPONENT "uru4000"
|
#define FP_COMPONENT "uru4000"
|
||||||
|
|
||||||
#include <nss.h>
|
#include <openssl/evp.h>
|
||||||
#include <pk11pub.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include "drivers_api.h"
|
#include "drivers_api.h"
|
||||||
|
|
||||||
@@ -148,10 +148,7 @@ struct _FpiDeviceUru4000
|
|||||||
int fwfixer_offset;
|
int fwfixer_offset;
|
||||||
unsigned char fwfixer_value;
|
unsigned char fwfixer_value;
|
||||||
|
|
||||||
CK_MECHANISM_TYPE cipher;
|
EVP_CIPHER_CTX *cipher_ctx;
|
||||||
PK11SlotInfo *slot;
|
|
||||||
PK11SymKey *symkey;
|
|
||||||
SECItem *param;
|
|
||||||
};
|
};
|
||||||
G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000,
|
G_DECLARE_FINAL_TYPE (FpiDeviceUru4000, fpi_device_uru4000, FPI, DEVICE_URU4000,
|
||||||
FpImageDevice);
|
FpImageDevice);
|
||||||
@@ -246,13 +243,29 @@ response_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *e
|
|||||||
fpi_ssm_mark_failed (ssm, error);
|
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
|
static void
|
||||||
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
|
challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *error)
|
||||||
{
|
{
|
||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||||
unsigned char respdata[CR_LENGTH];
|
unsigned char respdata[CR_LENGTH * 2];
|
||||||
PK11Context *ctx;
|
|
||||||
int outlen;
|
int outlen;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
@@ -261,17 +274,39 @@ challenge_cb (FpiUsbTransfer *transfer, FpDevice *dev, void *user_data, GError *
|
|||||||
return;
|
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 */
|
/* submit response */
|
||||||
/* produce response from challenge */
|
/* produce response from challenge */
|
||||||
ctx = PK11_CreateContextBySymKey (self->cipher, CKA_ENCRYPT,
|
if (!EVP_EncryptUpdate (self->cipher_ctx, respdata, &outlen, transfer->buffer, CR_LENGTH))
|
||||||
self->symkey, self->param);
|
|
||||||
if (PK11_CipherOp (ctx, respdata, &outlen, CR_LENGTH, transfer->buffer, CR_LENGTH) != SECSuccess ||
|
|
||||||
PK11_Finalize (ctx) != SECSuccess)
|
|
||||||
{
|
{
|
||||||
fp_err ("Failed to encrypt challenge data");
|
fpi_ssm_mark_failed (ssm, openssl_device_error ());
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, "Failed to encrypt challenge data");
|
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)
|
if (!error)
|
||||||
write_regs (FP_IMAGE_DEVICE (dev), REG_RESPONSE, CR_LENGTH, respdata, response_cb, ssm);
|
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;
|
g_autoptr(GPtrArray) interfaces = NULL;
|
||||||
GUsbInterface *iface = NULL;
|
GUsbInterface *iface = NULL;
|
||||||
guint64 driver_data;
|
guint64 driver_data;
|
||||||
SECStatus rv;
|
|
||||||
SECItem item;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
|
interfaces = g_usb_device_get_interfaces (fpi_device_get_usb_device (FP_DEVICE (dev)), &error);
|
||||||
@@ -1343,20 +1376,6 @@ dev_init (FpImageDevice *dev)
|
|||||||
return;
|
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);
|
self = FPI_DEVICE_URU4000 (dev);
|
||||||
|
|
||||||
g_clear_pointer (&self->rand, g_rand_free);
|
g_clear_pointer (&self->rand, g_rand_free);
|
||||||
@@ -1369,35 +1388,17 @@ dev_init (FpImageDevice *dev)
|
|||||||
self->interface = g_usb_interface_get_number (iface);
|
self->interface = g_usb_interface_get_number (iface);
|
||||||
|
|
||||||
/* Set up encryption */
|
/* Set up encryption */
|
||||||
self->cipher = CKM_AES_ECB;
|
if (!(self->cipher_ctx = EVP_CIPHER_CTX_new ()))
|
||||||
self->slot = PK11_GetBestSlot (self->cipher, NULL);
|
|
||||||
if (self->slot == NULL)
|
|
||||||
{
|
{
|
||||||
fp_err ("could not get encryption slot");
|
fpi_image_device_open_complete (dev, openssl_device_error ());
|
||||||
fpi_image_device_open_complete (dev,
|
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"Could not get encryption slot"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
item.type = siBuffer;
|
|
||||||
item.data = (unsigned char *) crkey;
|
if (!EVP_EncryptInit_ex (self->cipher_ctx, EVP_aes_128_ecb (), NULL, crkey, NULL))
|
||||||
item.len = sizeof (crkey);
|
|
||||||
self->symkey = PK11_ImportSymKey (self->slot,
|
|
||||||
self->cipher,
|
|
||||||
PK11_OriginUnwrap,
|
|
||||||
CKA_ENCRYPT,
|
|
||||||
&item, NULL);
|
|
||||||
if (self->symkey == NULL)
|
|
||||||
{
|
{
|
||||||
fp_err ("failed to import key into NSS");
|
fpi_image_device_open_complete (dev, openssl_device_error ());
|
||||||
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"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->param = PK11_ParamFromIV (self->cipher, NULL);
|
|
||||||
|
|
||||||
fpi_image_device_open_complete (dev, NULL);
|
fpi_image_device_open_complete (dev, NULL);
|
||||||
}
|
}
|
||||||
@@ -1408,14 +1409,7 @@ dev_deinit (FpImageDevice *dev)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
|
||||||
|
|
||||||
if (self->symkey)
|
g_clear_pointer (&self->cipher_ctx, EVP_CIPHER_CTX_free);
|
||||||
PK11_FreeSymKey (self->symkey);
|
|
||||||
if (self->param)
|
|
||||||
SECITEM_FreeItem (self->param, PR_TRUE);
|
|
||||||
if (self->slot)
|
|
||||||
PK11_FreeSlot (self->slot);
|
|
||||||
|
|
||||||
NSS_Shutdown ();
|
|
||||||
|
|
||||||
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
g_usb_device_release_interface (fpi_device_get_usb_device (FP_DEVICE (dev)),
|
||||||
self->interface, 0, &error);
|
self->interface, 0, &error);
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ helper_sources = {
|
|||||||
[ 'drivers/aesx660.c' ],
|
[ 'drivers/aesx660.c' ],
|
||||||
'aes3k' :
|
'aes3k' :
|
||||||
[ 'drivers/aes3k.c' ],
|
[ 'drivers/aes3k.c' ],
|
||||||
'nss' :
|
'openssl' :
|
||||||
[ ],
|
[ ],
|
||||||
'udev' :
|
'udev' :
|
||||||
[ ],
|
[ ],
|
||||||
|
|||||||
12
meson.build
12
meson.build
@@ -203,7 +203,7 @@ driver_helper_mapping = {
|
|||||||
'aes2660' : [ 'aeslib', 'aesx660' ],
|
'aes2660' : [ 'aeslib', 'aesx660' ],
|
||||||
'aes3500' : [ 'aeslib', 'aes3k' ],
|
'aes3500' : [ 'aeslib', 'aes3k' ],
|
||||||
'aes4000' : [ 'aeslib', 'aes3k' ],
|
'aes4000' : [ 'aeslib', 'aes3k' ],
|
||||||
'uru4000' : [ 'nss' ],
|
'uru4000' : [ 'openssl' ],
|
||||||
'elanspi' : [ 'udev' ],
|
'elanspi' : [ 'udev' ],
|
||||||
'virtual_image' : [ 'virtual' ],
|
'virtual_image' : [ 'virtual' ],
|
||||||
'virtual_device' : [ 'virtual' ],
|
'virtual_device' : [ 'virtual' ],
|
||||||
@@ -260,13 +260,13 @@ foreach i : driver_helpers
|
|||||||
|
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||||
optional_deps += imaging_dep
|
optional_deps += imaging_dep
|
||||||
elif i == 'nss'
|
elif i == 'openssl'
|
||||||
nss_dep = dependency('nss', required: false)
|
openssl_dep = dependency('openssl', version: '>= 3.0', required: false)
|
||||||
if not nss_dep.found()
|
if not openssl_dep.found()
|
||||||
error('nss is required for @0@ and possibly others'.format(driver))
|
error('OpenSSL is required for @0@ and possibly others'.format(driver))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
optional_deps += nss_dep
|
optional_deps += openssl_dep
|
||||||
elif i == 'udev'
|
elif i == 'udev'
|
||||||
install_udev_rules = true
|
install_udev_rules = true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user