aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-10-13 06:16:22 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-10-13 06:24:43 +0200
commit65f1016427f349073387b89a16e0e0b67a0692e3 (patch)
tree44f3c45e94fec8ddc7f357d597beaac1c3f57e09
parentInitial commit. (diff)
downloadhasplib-master.tar.xz
hasplib-master.zip
Simplify cryptoHEADmaster
-rw-r--r--Makefile4
-rw-r--r--hasplib.c51
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 <string.h>
#include <libusb.h>
-#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;