From 65f1016427f349073387b89a16e0e0b67a0692e3 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 13 Oct 2018 06:16:22 +0200 Subject: Simplify crypto --- Makefile | 4 ++-- hasplib.c | 51 ++++++++++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 66561f1..392a748 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS ?= -O3 -march=native -fomit-frame-pointer -pipe +CFLAGS ?= -O3 -march=native -pipe CFLAGS += -std=c99 $(shell pkg-config --cflags libusb-1.0) LDLIBS = $(shell pkg-config --libs libusb-1.0) @@ -11,6 +11,6 @@ hasplib-simple.c: hasplib.c hasplib.h test: hasplib.c hasplib-simple.c test.c clean: - rm -v test + @rm -fv test .PHONY: all clean diff --git a/hasplib.c b/hasplib.c index 70170da..455d194 100644 --- a/hasplib.c +++ b/hasplib.c @@ -23,20 +23,18 @@ #include #include -#pragma pack(1) struct hasp_response { uint8_t status; uint8_t status_checksum; uint8_t data[16]; }; -#pragma pack() struct _hasp_dongle { libusb_device_handle *handle; bool initialized; - uint16_t cipher_key1; - uint16_t cipher_key2; + uint16_t lfsr; + uint16_t polynomial_bottom; uint16_t password1; uint16_t password2; @@ -53,34 +51,37 @@ enum HASP_FUNCTION_LIST { }; enum HASP_STATUS { - HASP_STATUS_OK = 0, - HASP_STATUS_ERROR = 1, - HASP_STATUS_INVALID_MEMORY_ADDRESS = 4, + HASP_STATUS_OK = 0x00, + HASP_STATUS_ERROR = 0x01, + HASP_STATUS_INVALID_MEMORY_ADDRESS = 0x04, HASP_STATUS_LAST = 0x1F, HASP_USB_ERROR = 0x6D }; static void cipher(hasp_dongle *dongle, uint8_t *buffer, size_t len) { - uint16_t key1 = dongle->cipher_key1, key2 = dongle->cipher_key2; - uint8_t xor_byte, multiplier; + const uint16_t polynomial = (dongle->polynomial_bottom >> 1) | 0x8000; + uint16_t lfsr = dongle->lfsr; + uint8_t stream_byte, output_bit; while (len--) { - xor_byte = 0; + stream_byte = 0; for (int i = 0; i < 4; ++i) { - multiplier = xor_byte << 1; - if (key1 & 1) { - multiplier |= 1; - key1 = ((key1 ^ key2) >> 1) | 0x8000; - } else - key1 >>= 1; - xor_byte = multiplier << 1; - if (key1 & 0x80) - xor_byte |= 1; + /* Output a bit from position 0 into stream_byte. */ + output_bit = lfsr & 1; + stream_byte = (stream_byte << 1) | output_bit; + lfsr >>= 1; + + /* Flip the tap bits if we output a 1. */ + lfsr ^= (-output_bit) & polynomial; + + /* Output a bit from position 7 into stream_byte. */ + output_bit = (lfsr >> 7) & 1; + stream_byte = (stream_byte << 1) | output_bit; } - *(buffer++) ^= xor_byte; + *(buffer++) ^= stream_byte; } - dongle->cipher_key1 = key1; + dongle->lfsr = lfsr; } static void usb_error(int error) @@ -108,7 +109,7 @@ static void make_request(hasp_dongle *dongle, uint8_t function, uint16_t param1, cipher(dongle, (uint8_t *)response, expected_data_len + 2); if (response->status == HASP_STATUS_OK) - dongle->cipher_key2 = (dongle->cipher_key2 & 0xFF) | (response->status_checksum << 8); + dongle->polynomial_bottom = (dongle->polynomial_bottom & 0xFF) | (response->status_checksum << 8); else if (retry && dongle->password1 && dongle->password2) { if (hasp_init(dongle) && hasp_login(dongle, dongle->password1, dongle->password2, NULL)) make_request(dongle, function, param1, param2, expected_data_len, cipher_params, false, response); @@ -203,11 +204,11 @@ void hasp_free_dongle(hasp_dongle *dongle) bool hasp_init(hasp_dongle *dongle) { - dongle->cipher_key1 = 0xFABE; - dongle->cipher_key2 = 0xA0CB; + dongle->lfsr = 0xFABE; + dongle->polynomial_bottom = 0xA0CB; struct hasp_response response; - make_request(dongle, HASP_FUNCTION_SET_KEYS, dongle->cipher_key1, 0 /* unused */, 5, false, false, &response); + make_request(dongle, HASP_FUNCTION_SET_KEYS, dongle->lfsr, 0 /* unused */, 5, false, false, &response); if (response.status == HASP_STATUS_OK && response.data[0] == 0x2 && response.data[1] == 0xEA /* 0x0A? */ && response.data[2] == 0x00) { dongle->initialized = true; -- cgit v1.2.3-59-g8ed1b