Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
KVER ?= $(shell uname -r)

ETC_PREFIX ?= /etc
DOC_PREFIX ?= /usr/share/doc/xpadneo
LIB_PREFIX := /usr/lib/modules/$(KVER)/kernel/drivers/hid

MODPROBE_CONFS := xpadneo.conf
UDEV_RULES := 60-xpadneo.rules 70-xpadneo-disable-hidraw.rules
Expand Down Expand Up @@ -47,9 +50,10 @@ install: build
$(DKMS) add hid-xpadneo

uninstall: VERSION
$(DKMS) remove "hid-xpadneo/$(shell cat VERSION)" --all
$(DKMS) remove "hid-xpadneo/$(shell cat VERSION)" --all || true
rm -Rf "$(PREFIX)/usr/src/hid-xpadneo-$(shell cat VERSION)"
rm -f $(DOCS:%=$(PREFIX)$(DOC_PREFIX)/%)
rm -f $(UDEV_RULES:%=$(PREFIX)$(ETC_PREFIX)/udev/rules.d/%)
rm -f $(MODPROBE_CONFS:%=$(PREFIX)$(ETC_PREFIX)/modprobe.d/%)
rm -f $(LIB_PREFIX)/hid-xpadneo.ko*
rmdir --ignore-fail-on-non-empty -p $(PREFIX)$(ETC_PREFIX)/modprobe.d $(PREFIX)$(ETC_PREFIX)/udev/rules.d $(PREFIX)$(DOC_PREFIX)
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,12 @@ Please feel free to add other distributions as well!
* If not using DKMS, follow steps above (generic distribution)
* Done!

#### Sign the module

If Secure Boot is enabled on your machine, your system will not accept to load it. You need to sign it:

* If using DKMS, run `sudo ./sign_and_install.sh` in lieu of `install.sh`
* For generic distribution, run `cd hid-xpadneo && sudo ./sign_and_install_generic.sh`

### Connection

Expand Down
60 changes: 54 additions & 6 deletions hid-xpadneo/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
KERNEL_SOURCE_DIR ?= /lib/modules/$(shell uname -r)/build
LD := ld.bfd
KVER ?= $(shell uname -r)
ETC_PREFIX ?= /etc
DOC_PREFIX ?= /usr/share/doc/xpadneo
LIB_PREFIX := /usr/lib/modules/$(KVER)/$(INSTALL_MOD_DIR)
KSRC := /lib/modules/$(KVER)/build
KDST := /lib/modules/$(KVER)/$(INSTALL_MOD_DIR)
INSTALL_MOD_DIR := kernel/drivers/hid
MOK_DIR ?= /var/lib/shim-signed/mok

MODPROBE_CONFS := xpadneo.conf
UDEV_RULES := 60-xpadneo.rules 70-xpadneo-disable-hidraw.rules
DOC_SRCS := ../NEWS.md $(wildcard ../docs/[0-9A-Z]*.md)
CONFIG_MODULE_SIG := y
CONFIG_MODULE_SIG_FORCE :=y
CONFIG_MODULE_SIG_HASH := sha512
CONFIG_MODULE_COMPRESS_NONE := y

all: modules

Expand All @@ -10,13 +26,45 @@ all: modules

# convenience rules for local development

clean modules modules_install: ../VERSION
$(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="kernel/drivers/hid" LD=$(LD) M=$(shell pwd)/src VERSION="$(shell cat ../VERSION)" $@
clean modules modules_sign modules_install: ../VERSION
$(MAKE) -C $(KERNEL_SOURCE_DIR) INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)" CONFIG_SYSTEM_TRUSTED_KEYS="$(MOK_DIR)/mok.pem" LD=$(LD) M=$(shell pwd)/src VERSION="$(shell cat ../VERSION)" $@

reinstall: unload modules modules_install load
reinstall-sign: unload modules modules_install load

unload:
[ "$(shell id -u)" = "0" ] || { echo >&2 "need to run with sudo"; exit 1; }
rmmod hid-xpadneo || echo "proceeding anyways"
rm /etc/udev/rules.d/60-xpadneo.rules || echo "remove error: proceeding anyways"
rm /etc/udev/rules.d/70-xpadneo-disable-hidraw.rules || echo "remove error: proceeding anyways"

load:
mkdir -p $(PREFIX)$(ETC_PREFIX)/modprobe.d $(PREFIX)$(ETC_PREFIX)/udev/rules.d $(PREFIX)$(DOC_PREFIX)
install -D -m 0644 -t $(PREFIX)$(ETC_PREFIX)/modprobe.d $(MODPROBE_CONFS:%=etc-modprobe.d/%)
install -D -m 0644 -t $(PREFIX)$(ETC_PREFIX)/udev/rules.d $(UDEV_RULES:%=etc-udev-rules.d/%)
install -D -m 0644 -t $(PREFIX)$(DOC_PREFIX) $(DOC_SRCS)
depmod -a
modprobe hid-xpadneo $(MOD_PARAMS)

uninstall: ../VERSION unload
rm -f $(LIB_PREFIX)/hid-xpadneo.ko*
rm -f $(KDST)/hid-xpadneo.ko*
rm -Rf "$(PREFIX)/usr/src/hid-xpadneo-$(shell cat $<)"
rm -f $(DOCS:%=$(PREFIX)$(DOC_PREFIX)/%)
rm -f $(UDEV_RULES:%=$(PREFIX)$(ETC_PREFIX)/udev/rules.d/%)
rm -f $(MODPROBE_CONFS:%=$(PREFIX)$(ETC_PREFIX)/modprobe.d/%)
rmdir --ignore-fail-on-non-empty -p $(PREFIX)$(ETC_PREFIX)/modprobe.d $(PREFIX)$(ETC_PREFIX)/udev/rules.d $(PREFIX)$(DOC_PREFIX) || true

sign: $(LIB_PREFIX)/hid-xpadneo.ko
[ "$(shell id -u)" = "0" ] || { echo >&2 "need to run with sudo"; exit 1; }
# Create the shim MOK keys if they do not exist
@update-secureboot-policy --new-key
@update-secureboot-policy --enroll-key
# TODO do we need both ?
$(KSRC)/scripts/sign-file sha256 $(MOK_DIR)/MOK.priv $(MOK_DIR)/MOK.der $<
$(KSRC)/scripts/sign-file sha256 $(MOK_DIR)/MOK.priv $(MOK_DIR)/MOK.der $(KDST)/hid-xpadneo.ko

reinstall: modules
sudo make modules_install
sudo rmmod hid-xpadneo || true
sudo modprobe hid-xpadneo $(MOD_PARAMS)
install-sign: modules modules_install sign load

# DKMS support rules

Expand Down
1 change: 1 addition & 0 deletions hid-xpadneo/etc-modprobe.d/xpadneo.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ alias hid:b0005g*v0000045Ep00000B05 hid_xpadneo
alias hid:b0005g*v0000045Ep00000B13 hid_xpadneo
alias hid:b0005g*v0000045Ep00000B20 hid_xpadneo
alias hid:b0005g*v0000045Ep00000B22 hid_xpadneo
softdep bluetooth pre: uhid
74 changes: 74 additions & 0 deletions hid-xpadneo/sign_and_install_generic.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
#set -x
set -e

# https://docs.fedoraproject.org/en-US/fedora/rawhide/system-administrators-guide/kernel-module-driver-configuration/Working_with_Kernel_Modules/#sect-signing-kernel-modules-for-secure-boot

source "$(dirname "$0")/../lib/mok.sh"

if [ "$EUID" -ne 0 ]
then error "Please run as root"
fi

DKMS_MOK_DIR="${DKMS_MOK_DIR:-/var/lib/shim-signed/mok}"

command -v openssl > /dev/null 2>&1 || warn "missing openssl, you will not be able to create a new MOK key"
command -v mokutil > /dev/null 2>&1 || warn "missing mokutil, you will not be able to sign the module"
[ -d /var/lib/shim-signed ] || error "missing shim-signed, unable to enrol MOK"

function install_xpadneo () {
info "start install_xpadneo"

# Uninstall previous version
rmmod hid-xpadneo > /dev/null 2>&1 || true

make modules
make modules_install

if [[ -z "$skip_signing" ]]; then
info "Now Manually signing"
signing_ko "$DKMS_MOK_DIR"
fi

depmod -a
modprobe hid-xpadneo
modinfo hid-xpadneo

if [ -d /sys/module/hid_xpadneo ]
then
info "hid_xpadneo loaded!"
# suggest to load uhid to support Bluetooth LE (for firmware 5.x)
if [ ! -d /sys/devices/virtual/misc/uhid ]
then info "you may need to run 'sudo modprobe uhid' to support firmware 5.x"
fi
else warn "failed to load hid_xpadneo"
fi

info "finished install_xpadneo"
}

if [ "$#" -ne "0" ]
then
signing_help
exit 0
else
if mokutil --sb-state | grep -q "SecureBoot enabled"; then
if ! [ -d /sys/module/hid_xpadneo ]
then
info "Secure boot is enabled and you have to setup signing"
if check_keys "$DKMS_MOK_DIR"
then
cert_setup "$DKMS_MOK_DIR"
install_xpadneo
fi
else
info "hid_xpadneo is loaded"
fi
else
warn "no need to sign module!"
export skip_signing=1
if ! [ -d /sys/module/hid_xpadneo ]
then install_xpadneo
fi
fi
fi
1 change: 1 addition & 0 deletions hid-xpadneo/src/hid-xpadneo.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ MODULE_AUTHOR("Florian Dollinger <[email protected]>");
MODULE_AUTHOR("Kai Krakow <[email protected]>");
MODULE_DESCRIPTION("Linux kernel driver for Xbox ONE S+ gamepads (BT), incl. FF");
MODULE_VERSION(XPADNEO_VERSION);
MODULE_SOFTDEP("bluetooth pre: uhid");

static u8 param_trigger_rumble_mode = 0;
module_param_named(trigger_rumble_mode, param_trigger_rumble_mode, byte, 0644);
Expand Down
96 changes: 96 additions & 0 deletions lib/mok.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/bash
# set -x

if [ ${EUID} -ne 0 ]; then
echo >&2 "ERROR: You most probably need superuser privileges to use this script, please run me via sudo!"
exit 3
fi

if [ -f "/usr/src/kernels/$(uname -r)/scripts" ]
then
kernel_src_dir="/usr/src/kernels/$(uname -r)"
else
kernel_src_dir="/usr/src/linux-headers-$(uname -r)"
fi

function info { echo -e "\e[32m[info] $*\e[39m"; }
function warn { echo -e "\e[33m[warn] $*\e[39m"; }
function error { echo -e "\e[31m[error] $*\e[39m"; exit 1; }

function signing_help () {
echo "
just run the script, reboot (you will have to type a pass you set) and run again!
"
}

function check_keys () {
if [ -f "$1/MOK.priv" ]
then
if mokutil --test-key "$1/MOK.der" | grep -q "already enrolled"
then
info "The Key is already trusted"
return 0
else
warn "The key exist but is not trusted yet, re-enroling it because it does not hurt. You missing a reboot?"
fi
else
info "No Private key found. Generating one"
update-secureboot-policy --new-key
fi
update-secureboot-policy --enroll-key
return 1
}

function cert_setup () {
if [ ! -f "$kernel_src_dir/certs/signing_key.pem" ]
then if [ ! -f "$1/MOK.pem" ]
then
info "Still no certificate associated to MOK found. Generating one"
generate_certificate "$1"
else
info "Existing signing certificate, installing it..."
install_certificate "$1"
fi
else info "Signing certificate already exists"
fi
info "finished cert_setup"
}

function generate_certificate () {
openssl x509 -inform der -in "$1/MOK.der" -out "$1/MOK.pem"

mkdir -p "$kernel_src_dir/certs/"
cp "$1/MOK.pem" "$kernel_src_dir/certs/signing_key.pem"
chmod 444 "$kernel_src_dir/certs/signing_key.pem"$
info "finished generate_certificate"

install_certificate "$1"
}

function install_certificate () {
# openssl_509_pass="${1:-$(openssl rand -hex 6)}"
# # echo "$openssl_509_pass" > "$1/.openssl_pass"
# # chmod 600 "$1/.openssl_pass"
# echo "The password for the x509 cert is: $openssl_509_pass"
# export KBUILD_SIGN_PIN="$(cat "$1/.openssl_pass" 2> /dev/null || echo "" )"

cp "$1/MOK.pem" "$kernel_src_dir/certs/signing_key.pem"
chmod 444 "$kernel_src_dir/certs/signing_key.pem"

info "finished install_certificate"
}

function signing_ko () {
module_ko_file=$(modinfo hid-xpadneo | awk '/^filename:/ { print $2 }')
if [ -z "$module_ko_file" ]
then error "Can not locate the folder used for hid-xpadneo.ko to sign it. Find the module and try to set the var 'ko_folder'"
fi
ko_path=${module_ko_file:-ko_folder/hid-xpadneo.ko%.ko*}

sign_file_dir="${sign_file_dir:-$kernel_src_dir/scripts}"
if "${sign_file_dir}/sign-file" sha256 "$1/MOK.priv" "$1/MOK.der" "${ko_path}"
then info "${ko_path}/hid-xpadneo.ko"
fi

info "finished signing_ko"
}
64 changes: 64 additions & 0 deletions sign_and_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
#set -x
set -e

# https://docs.fedoraproject.org/en-US/fedora/rawhide/system-administrators-guide/kernel-module-driver-configuration/Working_with_Kernel_Modules/#sect-signing-kernel-modules-for-secure-boot

source "$(dirname "$0")/lib/mok.sh"

dkms_mok_dir="${dkms_mok_dir:-/var/lib/shim-signed/mok}"

command -v openssl > /dev/null 2>&1 || warn "missing openssl, you will not be able to create a new MOK key"
command -v mokutil > /dev/null 2>&1 || warn "missing mokutil, you will not be able to sign the module"
[ -d /var/lib/shim-signed ] || error "missing shim-signed, unable to enrol MOK"

function install_xpadneo () {
info "start install_xpadneo"

# Uninstall previous version
source "$(dirname "$0")/uninstall.sh"

# Try to load uhid module if not found, to support firmware 5.x
if [ ! -d /sys/devices/virtual/misc/uhid ]
then modprobe uhid
fi
source "$(dirname "$0")/install.sh"

module_ko_file=$(modinfo hid-xpadneo | awk '/^filename:/ { print $2 }')
if [ -z "$module_ko_file" ]
then error "Module compilation or installation failed"
fi

depmod -a

if modprobe hid-xpadneo
then
modinfo hid-xpadneo
info "finished install_xpadneo"

if [ -d /sys/module/hid_xpadneo ]
then info "hid_xpadneo loaded!"
else warn "failed to load hid_xpadneo (check for errors by running 'sudo dmesg')"
fi
else warn "failed to load hid_xpadneo"
fi
}

if [ "$#" -ne "0" ]
then
signing_help
exit 0
else
if mokutil --sb-state | grep -q "SecureBoot enabled"
then warn "no need to sign module!"
fi

if ! [ -d /sys/module/hid_xpadneo ]
then
info "Secure boot is enabled and you have to setup signing"
if check_keys "$dkms_mok_dir"
then install_xpadneo
fi
else info "hid_xpadneo is already loaded"
fi
fi