summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoderick Colenbrander <roderick.colenbrander@sony.com>2016-10-07 12:39:36 -0700
committerSiarhei Vishniakou <svv@google.com>2019-11-07 11:13:04 -0600
commit9f2d65c8dcaf3fe815de68db8a5801d74a3436fa (patch)
tree31c97b68d0042de7149f3f64418d8dd90aa99343
parentb3287a7c7caf8e7b61c86e3f9e90ec1c7cfabd5b (diff)
UPSTREAM: HID: sony: Perform CRC check on bluetooth input packets
Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz> (cherry picked from commit 49b9ca6c6c361a19d223ff84bd0ff871c01b528a) Bug: 111431828 Signed-off-by: Kim Low <kim-huei.low@sony.com> Change-Id: I433db7acd8a8e96d4c859e1c7df2abc7d8136085 Signed-off-by: Siarhei Vishniakou <svv@google.com>
-rw-r--r--drivers/hid/hid-sony.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 4215b945e30c..e63911ed65ba 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -36,6 +36,8 @@
#include <linux/list.h>
#include <linux/idr.h>
#include <linux/input/mt.h>
+#include <linux/crc32.h>
+#include <asm/unaligned.h>
#include "hid-ids.h"
@@ -1019,6 +1021,7 @@ struct motion_output_report_02 {
#define DS4_FEATURE_REPORT_0x02_SIZE 37
#define DS4_FEATURE_REPORT_0x81_SIZE 7
+#define DS4_INPUT_REPORT_0x11_SIZE 78
#define DS4_OUTPUT_REPORT_0x05_SIZE 32
#define DS4_OUTPUT_REPORT_0x11_SIZE 78
#define SIXAXIS_REPORT_0xF2_SIZE 17
@@ -1319,6 +1322,21 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
&& rd[0] == 0x11 && size == 78)) {
+ if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
+ /* CRC check */
+ u8 bthdr = 0xA1;
+ u32 crc;
+ u32 report_crc;
+
+ crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
+ crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4);
+ report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]);
+ if (crc != report_crc) {
+ hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x\n",
+ report_crc, crc);
+ return -EILSEQ;
+ }
+ }
dualshock4_parse_report(sc, rd, size);
}