Skip to content

Commit

Permalink
experimental nfc support on linux
Browse files Browse the repository at this point in the history
joint work w/ Ludvig Michaelsson, who did a lot of the heavy
lifting. thank you!
  • Loading branch information
martelletto committed Dec 22, 2020
1 parent d02a261 commit 0a1a5ce
Show file tree
Hide file tree
Showing 11 changed files with 1,437 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ file for the full license text.

*libfido2* is known to work on Linux, MacOS, Windows, OpenBSD, and FreeBSD.

On Linux, *experimental* NFC support is available in git HEAD.

=== Documentation

Documentation is available in troff and HTML formats. An
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ elseif(WIN32)
elseif(APPLE)
list(APPEND FIDO_SOURCES hid_osx.c)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND FIDO_SOURCES hid_linux.c hid_unix.c)
list(APPEND FIDO_SOURCES hid_linux.c hid_unix.c netlink.c nfc_linux.c)
elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
list(APPEND FIDO_SOURCES hid_netbsd.c hid_unix.c)
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
Expand Down
27 changes: 27 additions & 0 deletions src/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
if (fido_dev_register_manifest_func(fido_hid_manifest) != FIDO_OK)
return (FIDO_ERR_INTERNAL);

#ifdef __linux__
if (fido_dev_register_manifest_func(fido_nfc_manifest) != FIDO_OK)
return (FIDO_ERR_INTERNAL);
#endif

for (curr = manifest_funcs; curr != NULL; curr = curr->next) {
curr_olen = 0;
m_func = curr->manifest_func;
Expand All @@ -297,6 +302,28 @@ fido_dev_open_with_info(fido_dev_t *dev)
int
fido_dev_open(fido_dev_t *dev, const char *path)
{
#ifdef __linux__
/*
* this is a hack to get existing applications up and running with nfc;
* it will *NOT* be part of a libfido2 release. to support nfc in your
* application, please change it to use fido_dev_open_with_info().
*/
if (strncmp(path, "/sys", strlen("/sys")) == 0 && strlen(path) > 4 &&
path[strlen(path) - 4] == 'n' && path[strlen(path) - 3] == 'f' &&
path[strlen(path) - 2] == 'c') {
dev->io_own = true;
dev->io = (fido_dev_io_t) {
fido_nfc_open,
fido_nfc_close,
fido_nfc_read,
fido_nfc_write,
};
dev->transport = (fido_dev_transport_t) {
fido_nfc_rx,
fido_nfc_tx,
};
}
#endif
return (fido_dev_open_wait(dev, path, -1));
}

Expand Down
11 changes: 10 additions & 1 deletion src/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ int fido_hid_unix_wait(int, int);
size_t fido_hid_report_in_len(void *);
size_t fido_hid_report_out_len(void *);

/* nfc i/o */
void *fido_nfc_open(const char *);
void fido_nfc_close(void *);
int fido_nfc_read(void *, unsigned char *, size_t, int);
int fido_nfc_write(void *, const unsigned char *, size_t);
int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);

/* generic i/o */
int fido_rx_cbor_status(fido_dev_t *, int);
int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int);
Expand Down Expand Up @@ -150,8 +158,9 @@ int fido_verify_sig_eddsa(const fido_blob_t *, const eddsa_pk_t *,
int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *,
const fido_blob_t *);

/* hid device manifest */
/* device manifest functions */
int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *);
int fido_nfc_manifest(fido_dev_info_t *, size_t, size_t *);

/* device manifest registration */
typedef int (*dev_manifest_func_t)(fido_dev_info_t *, size_t, size_t *);
Expand Down
1 change: 1 addition & 0 deletions src/fido/param.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define U2F_AUTH_CHECK 0x07

/* ISO7816-4 status words. */
#define SW1_MORE_DATA 0x61
#define SW_CONDITIONS_NOT_SATISFIED 0x6985
#define SW_WRONG_DATA 0x6a80
#define SW_NO_ERROR 0x9000
Expand Down
3 changes: 2 additions & 1 deletion src/iso7816.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "fido.h"

iso7816_apdu_t *
iso7816_new(uint8_t ins, uint8_t p1, uint16_t payload_len)
iso7816_new(uint8_t cla, uint8_t ins, uint8_t p1, uint16_t payload_len)
{
iso7816_apdu_t *apdu;
size_t alloc_len;
Expand All @@ -21,6 +21,7 @@ iso7816_new(uint8_t ins, uint8_t p1, uint16_t payload_len)
apdu->alloc_len = alloc_len;
apdu->payload_len = payload_len;
apdu->payload_ptr = apdu->payload;
apdu->header.cla = cla;
apdu->header.ins = ins;
apdu->header.p1 = p1;
apdu->header.lc2 = (uint8_t)((payload_len >> 8) & 0xff);
Expand Down
2 changes: 1 addition & 1 deletion src/iso7816.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct iso7816_apdu {

const unsigned char *iso7816_ptr(const iso7816_apdu_t *);
int iso7816_add(iso7816_apdu_t *, const void *, size_t);
iso7816_apdu_t *iso7816_new(uint8_t, uint8_t, uint16_t);
iso7816_apdu_t *iso7816_new(uint8_t, uint8_t, uint8_t, uint16_t);
size_t iso7816_len(const iso7816_apdu_t *);
void iso7816_free(iso7816_apdu_t **);

Expand Down
Loading

0 comments on commit 0a1a5ce

Please sign in to comment.