mirror of
https://github.com/cecio/USBvalve.git
synced 2025-12-06 03:41:45 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c493681cc | ||
|
|
b87b518552 | ||
|
|
385a67144a | ||
|
|
df739adf29 | ||
|
|
5126ce40d7 | ||
|
|
f7a1165cae | ||
|
|
8b3f6d3223 | ||
|
|
2d248742e3 | ||
|
|
9b92c0b97a | ||
|
|
d92080cfca | ||
|
|
4ed324a73b | ||
|
|
39b0a09ff8 | ||
|
|
adaf489a82 |
@@ -27,12 +27,13 @@ RUN cd /app \
|
||||
&& arduino-cli lib install "Adafruit TinyUSB Library" \
|
||||
&& arduino-cli lib install "ssd1306" \
|
||||
&& arduino-cli lib install "Pico PIO USB" \
|
||||
&& arduino-cli lib install "XxHash_arduino" \
|
||||
&& arduino-cli lib install "SSD1306Ascii"
|
||||
|
||||
# Compilation setup
|
||||
RUN echo "#!/bin/bash" > /app/entrypoint.sh \
|
||||
&& echo "export PATH=\$PATH:/app/arduino-cli/bin" >> /app/entrypoint.sh \
|
||||
&& echo "arduino-cli compile --fqbn rp2040:rp2040:rpipico --board-options \"usbstack=tinyusb\" --board-options \"freq=240\" --output-dir \"/mnt/USBvalve_out\" \"\$1\"" >> /app/entrypoint.sh \
|
||||
&& echo "arduino-cli compile --fqbn rp2040:rp2040:rpipico --board-options \"usbstack=tinyusb\" --board-options \"freq=120\" --output-dir \"/mnt/USBvalve_out\" \"\$1\"" >> /app/entrypoint.sh \
|
||||
&& chmod +x /app/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
|
||||
10
README.md
10
README.md
@@ -1,4 +1,4 @@
|
||||
<h1><img width="200" alt="logo, landscape, dark text, transparent background" src="https://github.com/cecio/USBvalve/blob/main/pictures/USBvalve_logo_scaled.png"></a></h1>
|
||||
<h1><img width="300" alt="logo, landscape, dark text, transparent background" src="https://github.com/cecio/USBvalve/blob/main/pictures/USBvalve_logo_scaled.png"></a></h1>
|
||||
|
||||
### *Expose USB activity on the fly*
|
||||
|
||||
@@ -43,7 +43,7 @@ If you prefer videos, you can also have a look to my [Insomni'hack Presentation]
|
||||
|
||||
`pictures`: images and resources used in this doc
|
||||
|
||||
`STL`: STL files for enclosure
|
||||
`STL`: STL files for enclosure. In `1.1` and `1.2` folders there are full enclosures (thanks to [WhistleMaster](https://github.com/WhistleMaster)). If you want something lighter to protect the LCD you can go with `USBvalve_sliding_cover.stl`.
|
||||
|
||||
## Build USBvalve
|
||||
|
||||
@@ -162,10 +162,8 @@ I grouped most of the variables you may want to modify in this section ([see Doc
|
||||
|
||||
Obviously you can also build your own firmware. To build the *standard* one I used:
|
||||
|
||||
- Arduino IDE 2.1.1
|
||||
- ~~as board I used `Raspberry Pi Pico - Arduino MBED OS RP2040` version `4.0.2`~~
|
||||
- ~~`Adafruit TinyUSB Library` version `1.14.4`. Newer versions are not working because the RPI SDK of the board is stick to an older version. May be migrate the entire project directly on Raspberry Pi Pico SDK is the solution here.~~
|
||||
- `Adafruit TinyUSB Library` version `2.2.2` and Board `Raspberry Pi RP2040 (3.3.0)` setting clock at 240MHz (overclock)
|
||||
- Arduino IDE `2.2.1`
|
||||
- `Adafruit TinyUSB Library` version `2.2.7`, `Pico-PIO-USB` version `0.5.2`, Board `Raspberry Pi RP2040 (3.6.2)` setting Tools=>CPU Speed at `120MHz` and Tools=>USB Stack to `Adafruit TinyUSB`
|
||||
- `ssd1306` OLED library version `1.8.3`
|
||||
|
||||
If you want to re-create a new fake filesystem, you may want to have a look to the `utils` folder, where I placed some utilities to build a new one.
|
||||
|
||||
BIN
STL/USBvalve_sliding_cover.stl
Normal file
BIN
STL/USBvalve_sliding_cover.stl
Normal file
Binary file not shown.
@@ -19,6 +19,8 @@
|
||||
#include <pio_usb.h>
|
||||
#include "Adafruit_TinyUSB.h"
|
||||
#include "SSD1306AsciiWire.h"
|
||||
#include <XxHash_arduino.h>
|
||||
#include <pico/stdlib.h>
|
||||
|
||||
//
|
||||
// BADUSB detector section
|
||||
@@ -52,7 +54,6 @@ SSD1306AsciiWire oled;
|
||||
#define FAKE_DISK_BLOCK_NUM 0x800
|
||||
#define DISK_BLOCK_SIZE 0x200
|
||||
#include "ramdisk.h"
|
||||
#include "quark.h"
|
||||
|
||||
Adafruit_USBD_MSC usb_msc;
|
||||
|
||||
@@ -74,11 +75,13 @@ bool activeState = false;
|
||||
//
|
||||
// USBvalve globals
|
||||
//
|
||||
#define VERSION "USBvalve - 0.12.1"
|
||||
#define VERSION "USBvalve - 0.14.2"
|
||||
boolean readme = false;
|
||||
boolean autorun = false;
|
||||
boolean written = false;
|
||||
boolean deleted = false;
|
||||
boolean written_reported = false;
|
||||
boolean deleted_reported = false;
|
||||
boolean hid_sent = false;
|
||||
boolean hid_reported = false;
|
||||
|
||||
@@ -110,16 +113,7 @@ boolean hid_reported = false;
|
||||
#define BYTES_TO_HASH_OFFSET 7 // Starting sector to check for consistency (FAT_DIRECTORY is 7)
|
||||
|
||||
// Burned hash to check consistency
|
||||
u8 valid_hash[WIDTH] = {
|
||||
0x60, 0xFB, 0x68, 0xB5, 0xB9, 0xE6, 0xF4, 0xB7,
|
||||
0x5F, 0xAD, 0x3C, 0x0D, 0xD3, 0x85, 0x01, 0x74,
|
||||
0xED, 0x70, 0x55, 0x55, 0xE8, 0x1D, 0xE4, 0xBB,
|
||||
0x4F, 0xC7, 0x2C, 0xA6, 0x7C, 0xC7, 0x79, 0x79,
|
||||
0xEF, 0x21, 0x81, 0xB0, 0xEB, 0xD1, 0xF1, 0x71,
|
||||
0x72, 0x37, 0x13, 0x0C, 0x28, 0x39, 0xC0, 0xB0
|
||||
};
|
||||
|
||||
u8 computed_hash[WIDTH] = { 0x00 };
|
||||
uint valid_hash = 2362816530;
|
||||
|
||||
// Core 0 Setup: will be used for the USB mass device functions
|
||||
void setup() {
|
||||
@@ -130,10 +124,6 @@ void setup() {
|
||||
// This could be used to change the serial number as well
|
||||
// TinyUSBDevice.setSerialDescriptor(USB_SERIAL);
|
||||
|
||||
// Check consistency of RAM FS
|
||||
// Add 11 bytes to skip the DISK_LABEL from the hashing
|
||||
quark(computed_hash, msc_disk[BYTES_TO_HASH_OFFSET] + 11, BYTES_TO_HASH);
|
||||
|
||||
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
|
||||
// Manual begin() is required on core without built-in support for TinyUSB such as
|
||||
// - mbed rp2040
|
||||
@@ -178,7 +168,11 @@ void setup() {
|
||||
oled.setScrollMode(SCROLL_MODE_AUTO);
|
||||
cls(); // Clear display
|
||||
|
||||
if (memcmp(computed_hash, valid_hash, WIDTH) == 0) {
|
||||
// Check consistency of RAM FS
|
||||
// Add 11 bytes to skip the DISK_LABEL from the hashing
|
||||
uint computed_hash;
|
||||
computed_hash = XXH32(msc_disk[BYTES_TO_HASH_OFFSET] + 11, BYTES_TO_HASH, 0);
|
||||
if (computed_hash == valid_hash) {
|
||||
oled.print("\n[+] Selftest: OK");
|
||||
} else {
|
||||
oled.print("\n[!] Selftest: KO");
|
||||
@@ -193,7 +187,8 @@ void setup() {
|
||||
|
||||
// Core 1 Setup: will be used for the USB host functions for BADUSB detector
|
||||
void setup1() {
|
||||
//while ( !Serial ) delay(10); // wait for native usb
|
||||
// Set a custom clock (multiple of 12Mhz) to achieve maximum compatibility
|
||||
set_sys_clock_khz(144000, true);
|
||||
|
||||
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
|
||||
pio_cfg.pin_dp = HOST_PIN_DP;
|
||||
@@ -218,6 +213,12 @@ void loop() {
|
||||
autorun = false;
|
||||
}
|
||||
|
||||
if (deleted == true && deleted_reported == false) {
|
||||
oled.print("\n[!] DELETING");
|
||||
deleted = false;
|
||||
deleted_reported = true;
|
||||
}
|
||||
|
||||
if (written == true && written_reported == false) {
|
||||
oled.print("\n[!] WRITING");
|
||||
written = false;
|
||||
@@ -282,14 +283,25 @@ int32_t msc_read_callback(uint32_t lba, void* buffer, uint32_t bufsize) {
|
||||
// This happens only for the "real" size of disk
|
||||
int32_t msc_write_callback(uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
|
||||
|
||||
// Check for file deletion at Block 7
|
||||
// The first char of filename is replaced with 0xE5, we are going
|
||||
// to check for it
|
||||
if (lba == 7) {
|
||||
if (buffer[32] == 0xE5 || buffer[64] == 0xE5 || buffer[160] == 0xE5) {
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// This check for writing of space. The LBA > 10 is set to avoid some
|
||||
// false positives, in particular on Windows Systems
|
||||
if (lba > 10) {
|
||||
written = true;
|
||||
}
|
||||
|
||||
// We are declaring a bigger size than what is actually allocated, so
|
||||
// this is protecting our memory integrity
|
||||
if (lba < DISK_BLOCK_NUM - 1) {
|
||||
// Writing buffer to "disk"
|
||||
uint8_t* addr = msc_disk[lba];
|
||||
memcpy(addr, buffer, bufsize);
|
||||
}
|
||||
@@ -365,10 +377,10 @@ void hexDump(unsigned char* data, size_t size) {
|
||||
}
|
||||
|
||||
// Reset the Pico
|
||||
void swreset()
|
||||
{
|
||||
watchdog_enable(1500, 1);
|
||||
while(1);
|
||||
void swreset() {
|
||||
watchdog_enable(1500, 1);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -415,7 +427,7 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
|
||||
|
||||
// Used in main loop to write output to OLED
|
||||
hid_sent = true;
|
||||
|
||||
|
||||
// Read the HID protocol
|
||||
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
||||
|
||||
|
||||
484
USBvalve/quark.c
484
USBvalve/quark.c
@@ -1,484 +0,0 @@
|
||||
/*
|
||||
USBvalve
|
||||
*/
|
||||
|
||||
/*
|
||||
Quark reference C implementation
|
||||
|
||||
Copyright (c) 2010-2014 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "quark.h"
|
||||
|
||||
#define DIGEST WIDTH
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pos; /* number of bytes read into x from current block */
|
||||
u32 x[WIDTH * 8]; /* one bit stored in each word */
|
||||
} hashState;
|
||||
|
||||
|
||||
#if defined(UQUARK)
|
||||
/* 17 bytes */
|
||||
u8 iv[] = { 0xd8, 0xda, 0xca, 0x44, 0x41, 0x4a, 0x09, 0x97,
|
||||
0x19, 0xc8, 0x0a, 0xa3, 0xaf, 0x06, 0x56, 0x44, 0xdb };
|
||||
#elif defined(DQUARK)
|
||||
/* 22 bytes */
|
||||
u8 iv[] = { 0xcc, 0x6c, 0x4a, 0xb7, 0xd1, 0x1f, 0xa9, 0xbd,
|
||||
0xf6, 0xee, 0xde, 0x03, 0xd8, 0x7b, 0x68, 0xf9,
|
||||
0x1b, 0xaa, 0x70, 0x6c, 0x20, 0xe9 };
|
||||
#elif defined(SQUARK)
|
||||
/* 32 bytes */
|
||||
u8 iv[] = { 0x39, 0x72, 0x51, 0xce, 0xe1, 0xde, 0x8a, 0xa7,
|
||||
0x3e, 0xa2, 0x62, 0x50, 0xc6, 0xd7, 0xbe, 0x12,
|
||||
0x8c, 0xd3, 0xe7, 0x9d, 0xd7, 0x18, 0xc2, 0x4b,
|
||||
0x8a, 0x19, 0xd0, 0x9c, 0x24, 0x92, 0xda, 0x5d };
|
||||
#elif defined(CQUARK)
|
||||
/* 48 bytes */
|
||||
u8 iv[] = { 0x3b, 0x45, 0x03, 0xec, 0x76, 0x62, 0xc3, 0xcb,
|
||||
0x30, 0xe0, 0x08, 0x37, 0xec, 0x8d, 0x38, 0xbb,
|
||||
0xe5, 0xff, 0x5a, 0xcd, 0x69, 0x01, 0xa2, 0x49,
|
||||
0x57, 0x50, 0xf9, 0x19, 0x8e, 0x2e, 0x3b, 0x58,
|
||||
0x52, 0xdc, 0xaa, 0x16, 0x62, 0xb7, 0xda, 0xd6,
|
||||
0x5f, 0xcb, 0x5a, 0x8a, 0x1f, 0x0d, 0x5f, 0xcc };
|
||||
#endif
|
||||
|
||||
void showstate(u32 *x) {
|
||||
|
||||
int i;
|
||||
u8 buf = 0;
|
||||
|
||||
for (i = 0; i < 8 * WIDTH; ++i) {
|
||||
buf ^= (1 & x[i]) << (7 - (i % 8));
|
||||
|
||||
if (((i % 8) == 7) && (i)) {
|
||||
printf("%02x", buf);
|
||||
buf = 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int permute_u(u32 *x) {
|
||||
/* state of 136=2x68 bits */
|
||||
#define ROUNDS_U 4 * 136
|
||||
#define N_LEN_U 68
|
||||
#define L_LEN_U 10
|
||||
|
||||
u32 *X, *Y, *L;
|
||||
u32 h;
|
||||
int i;
|
||||
|
||||
X = (u32 *)malloc((N_LEN_U + ROUNDS_U) * sizeof(u32));
|
||||
Y = (u32 *)malloc((N_LEN_U + ROUNDS_U) * sizeof(u32));
|
||||
L = (u32 *)malloc((L_LEN_U + ROUNDS_U) * sizeof(u32));
|
||||
|
||||
/* local copy of the state in the registers*/
|
||||
for (i = 0; i < N_LEN_U; ++i) {
|
||||
X[i] = x[i];
|
||||
Y[i] = x[i + N_LEN_U];
|
||||
}
|
||||
|
||||
/* initialize the LFSR to 11..11 */
|
||||
for (i = 0; i < L_LEN_U; ++i)
|
||||
L[i] = 0xFFFFFFFF;
|
||||
|
||||
/* iterate rounds */
|
||||
for (i = 0; i < ROUNDS_U; ++i) {
|
||||
|
||||
/* indices up to i+59, for 8x parallelizibility*/
|
||||
|
||||
/* need X[i] as linear term only, for invertibility */
|
||||
X[N_LEN_U + i] = X[i] ^ Y[i];
|
||||
X[N_LEN_U + i] ^= X[i + 9] ^ X[i + 14] ^ X[i + 21] ^ X[i + 28] ^ X[i + 33] ^ X[i + 37] ^ X[i + 45] ^ X[i + 52] ^ X[i + 55] ^ X[i + 50] ^ (X[i + 59] & X[i + 55]) ^ (X[i + 37] & X[i + 33]) ^ (X[i + 15] & X[i + 9]) ^ (X[i + 55] & X[i + 52] & X[i + 45]) ^ (X[i + 33] & X[i + 28] & X[i + 21]) ^ (X[i + 59] & X[i + 45] & X[i + 28] & X[i + 9]) ^ (X[i + 55] & X[i + 52] & X[i + 37] & X[i + 33]) ^ (X[i + 59] & X[i + 55] & X[i + 21] & X[i + 15]) ^ (X[i + 59] & X[i + 55] & X[i + 52] & X[i + 45] & X[i + 37]) ^ (X[i + 33] & X[i + 28] & X[i + 21] & X[i + 15] & X[i + 9]) ^ (X[i + 52] & X[i + 45] & X[i + 37] & X[i + 33] & X[i + 28] & X[i + 21]);
|
||||
|
||||
/* need Y[i] as linear term only, for invertibility */
|
||||
Y[N_LEN_U + i] = Y[i];
|
||||
Y[N_LEN_U + i] ^= Y[i + 7] ^ Y[i + 16] ^ Y[i + 20] ^ Y[i + 30] ^ Y[i + 35] ^ Y[i + 37] ^ Y[i + 42] ^ Y[i + 51] ^ Y[i + 54] ^ Y[i + 49] ^ (Y[i + 58] & Y[i + 54]) ^ (Y[i + 37] & Y[i + 35]) ^ (Y[i + 15] & Y[i + 7]) ^ (Y[i + 54] & Y[i + 51] & Y[i + 42]) ^ (Y[i + 35] & Y[i + 30] & Y[i + 20]) ^ (Y[i + 58] & Y[i + 42] & Y[i + 30] & Y[i + 7]) ^ (Y[i + 54] & Y[i + 51] & Y[i + 37] & Y[i + 35]) ^ (Y[i + 58] & Y[i + 54] & Y[i + 20] & Y[i + 15]) ^ (Y[i + 58] & Y[i + 54] & Y[i + 51] & Y[i + 42] & Y[i + 37]) ^ (Y[i + 35] & Y[i + 30] & Y[i + 20] & Y[i + 15] & Y[i + 7]) ^ (Y[i + 51] & Y[i + 42] & Y[i + 37] & Y[i + 35] & Y[i + 30] & Y[i + 20]);
|
||||
|
||||
/* need L[i] as linear term only, for invertibility */
|
||||
L[L_LEN_U + i] = L[i];
|
||||
L[L_LEN_U + i] ^= L[i + 3];
|
||||
|
||||
/* compute output of the h function */
|
||||
h = X[i + 25] ^ Y[i + 59] ^ (Y[i + 3] & X[i + 55]) ^ (X[i + 46] & X[i + 55]) ^ (X[i + 55] & Y[i + 59]) ^ (Y[i + 3] & X[i + 25] & X[i + 46]) ^ (Y[i + 3] & X[i + 46] & X[i + 55]) ^ (Y[i + 3] & X[i + 46] & Y[i + 59]) ^ (X[i + 25] & X[i + 46] & Y[i + 59] & L[i]) ^ (X[i + 25] & L[i]);
|
||||
h ^= X[i + 1] ^ Y[i + 2] ^ X[i + 4] ^ Y[i + 10] ^ X[i + 31] ^ Y[i + 43] ^ X[i + 56] ^ L[i];
|
||||
|
||||
/* feedback of h into the registers */
|
||||
X[N_LEN_U + i] ^= h;
|
||||
Y[N_LEN_U + i] ^= h;
|
||||
}
|
||||
|
||||
/* copy final state into hashState */
|
||||
for (i = 0; i < N_LEN_U; ++i) {
|
||||
x[i] = X[ROUNDS_U + i];
|
||||
x[i + N_LEN_U] = Y[ROUNDS_U + i];
|
||||
}
|
||||
|
||||
free(X);
|
||||
free(Y);
|
||||
free(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int permute_d(u32 *x) {
|
||||
/* state of 176=2x88 bits */
|
||||
#define ROUNDS_D 4 * 176
|
||||
#define N_LEN_D 88
|
||||
#define L_LEN_D 10
|
||||
|
||||
u32 *X, *Y, *L;
|
||||
u32 h;
|
||||
int i;
|
||||
|
||||
X = (u32 *)malloc((N_LEN_D + ROUNDS_D) * sizeof(u32));
|
||||
Y = (u32 *)malloc((N_LEN_D + ROUNDS_D) * sizeof(u32));
|
||||
L = (u32 *)malloc((L_LEN_D + ROUNDS_D) * sizeof(u32));
|
||||
|
||||
/* local copy of the state in the registers*/
|
||||
for (i = 0; i < N_LEN_D; ++i) {
|
||||
X[i] = x[i];
|
||||
Y[i] = x[i + N_LEN_D];
|
||||
}
|
||||
|
||||
/* initialize the LFSR to 11..11 */
|
||||
for (i = 0; i < L_LEN_D; ++i)
|
||||
L[i] = 0xFFFFFFFF;
|
||||
|
||||
/* iterate rounds */
|
||||
for (i = 0; i < ROUNDS_D; ++i) {
|
||||
|
||||
/* need X[i] as linear term only, for invertibility */
|
||||
X[N_LEN_D + i] = X[i] ^ Y[i];
|
||||
X[N_LEN_D + i] ^= X[i + 11] ^ X[i + 18] ^ X[i + 27] ^ X[i + 36] ^ X[i + 42] ^ X[i + 47] ^ X[i + 58] ^ X[i + 67] ^ X[i + 71] ^ X[i + 64] ^ (X[i + 79] & X[i + 71]) ^ (X[i + 47] & X[i + 42]) ^ (X[i + 19] & X[i + 11]) ^ (X[i + 71] & X[i + 67] & X[i + 58]) ^ (X[i + 42] & X[i + 36] & X[i + 27]) ^ (X[i + 79] & X[i + 58] & X[i + 36] & X[i + 11]) ^ (X[i + 71] & X[i + 67] & X[i + 47] & X[i + 42]) ^ (X[i + 79] & X[i + 71] & X[i + 27] & X[i + 19]) ^ (X[i + 79] & X[i + 71] & X[i + 67] & X[i + 58] & X[i + 47]) ^ (X[i + 42] & X[i + 36] & X[i + 27] & X[i + 19] & X[i + 11]) ^ (X[i + 67] & X[i + 58] & X[i + 47] & X[i + 42] & X[i + 36] & X[i + 27]);
|
||||
|
||||
|
||||
/* need Y[i] as linear term only, for invertibility */
|
||||
Y[N_LEN_D + i] = Y[i];
|
||||
Y[N_LEN_D + i] ^= Y[i + 9] ^ Y[i + 20] ^ Y[i + 25] ^ Y[i + 38] ^ Y[i + 44] ^ Y[i + 47] ^ Y[i + 54] ^ Y[i + 67] ^ Y[i + 69] ^ Y[i + 63] ^ (Y[i + 78] & Y[i + 69]) ^ (Y[i + 47] & Y[i + 44]) ^ (Y[i + 19] & Y[i + 9]) ^ (Y[i + 69] & Y[i + 67] & Y[i + 54]) ^ (Y[i + 44] & Y[i + 38] & Y[i + 25]) ^ (Y[i + 78] & Y[i + 54] & Y[i + 38] & Y[i + 9]) ^ (Y[i + 69] & Y[i + 67] & Y[i + 47] & Y[i + 44]) ^ (Y[i + 78] & Y[i + 69] & Y[i + 25] & Y[i + 19]) ^ (Y[i + 78] & Y[i + 69] & Y[i + 67] & Y[i + 54] & Y[i + 47]) ^ (Y[i + 44] & Y[i + 38] & Y[i + 25] & Y[i + 19] & Y[i + 9]) ^ (Y[i + 67] & Y[i + 54] & Y[i + 47] & Y[i + 44] & Y[i + 38] & Y[i + 25]);
|
||||
|
||||
/* need L[i] as linear term only, for invertibility */
|
||||
L[L_LEN_D + i] = L[i];
|
||||
L[L_LEN_D + i] ^= L[i + 3]; // linear feedback here
|
||||
|
||||
/* compute output of the h function */
|
||||
h = X[i + 35] ^ Y[i + 79] ^ (Y[i + 4] & X[i + 68]) ^ (X[i + 57] & X[i + 68]) ^ (X[i + 68] & Y[i + 79]) ^ (Y[i + 4] & X[i + 35] & X[i + 57]) ^ (Y[i + 4] & X[i + 57] & X[i + 68]) ^ (Y[i + 4] & X[i + 57] & Y[i + 79]) ^ (X[i + 35] & X[i + 57] & Y[i + 79] & L[i]) ^ (X[i + 35] & L[i]);
|
||||
h ^= X[i + 1] ^ Y[i + 2] ^ X[i + 5] ^ Y[i + 12] ^ X[i + 40] ^ Y[i + 55] ^ X[i + 72] ^ L[i];
|
||||
h ^= Y[i + 24] ^ X[i + 48] ^ Y[i + 61];
|
||||
|
||||
/* feedback of h into the registers */
|
||||
X[N_LEN_D + i] ^= h;
|
||||
Y[N_LEN_D + i] ^= h;
|
||||
}
|
||||
|
||||
/* copy final state into hashState */
|
||||
for (i = 0; i < N_LEN_D; ++i) {
|
||||
x[i] = X[ROUNDS_D + i];
|
||||
x[i + N_LEN_D] = Y[ROUNDS_D + i];
|
||||
}
|
||||
|
||||
free(X);
|
||||
free(Y);
|
||||
free(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int permute_s(u32 *x) {
|
||||
/* state of 256=2x128 bits */
|
||||
#define ROUNDS_S 4 * 256
|
||||
#define N_LEN_S 128
|
||||
#define L_LEN_S 10
|
||||
|
||||
u32 *X, *Y, *L;
|
||||
u32 h;
|
||||
int i;
|
||||
|
||||
X = (u32 *)malloc((N_LEN_S + ROUNDS_S) * sizeof(u32));
|
||||
Y = (u32 *)malloc((N_LEN_S + ROUNDS_S) * sizeof(u32));
|
||||
L = (u32 *)malloc((L_LEN_S + ROUNDS_S) * sizeof(u32));
|
||||
|
||||
/* local copy of the state in the registers*/
|
||||
for (i = 0; i < N_LEN_S; ++i) {
|
||||
X[i] = x[i];
|
||||
Y[i] = x[i + N_LEN_S];
|
||||
}
|
||||
|
||||
/* initialize the LFSR to 11..11 */
|
||||
for (i = 0; i < L_LEN_S; ++i)
|
||||
L[i] = 0xFFFFFFFF;
|
||||
|
||||
/* iterate rounds */
|
||||
for (i = 0; i < ROUNDS_S; ++i) {
|
||||
|
||||
/* need X[i] as linear term only, for invertibility */
|
||||
X[N_LEN_S + i] = X[i] ^ Y[i];
|
||||
X[N_LEN_S + i] ^= X[i + 16] ^ X[i + 26] ^ X[i + 39] ^ X[i + 52] ^ X[i + 61] ^ X[i + 69] ^ X[i + 84] ^ X[i + 97] ^ X[i + 103] ^ X[i + 94] ^ (X[i + 111] & X[i + 103]) ^ (X[i + 69] & X[i + 61]) ^ (X[i + 28] & X[i + 16]) ^ (X[i + 103] & X[i + 97] & X[i + 84]) ^ (X[i + 61] & X[i + 52] & X[i + 39]) ^ (X[i + 111] & X[i + 84] & X[i + 52] & X[i + 16]) ^ (X[i + 103] & X[i + 97] & X[i + 69] & X[i + 61]) ^ (X[i + 111] & X[i + 103] & X[i + 39] & X[i + 28]) ^ (X[i + 111] & X[i + 103] & X[i + 97] & X[i + 84] & X[i + 69]) ^ (X[i + 61] & X[i + 52] & X[i + 39] & X[i + 28] & X[i + 16]) ^ (X[i + 97] & X[i + 84] & X[i + 69] & X[i + 61] & X[i + 52] & X[i + 39]);
|
||||
|
||||
/* need Y[i] as linear term only, for invertibility */
|
||||
Y[N_LEN_S + i] = Y[i];
|
||||
Y[N_LEN_S + i] ^= Y[i + 13] ^ Y[i + 30] ^ Y[i + 37] ^ Y[i + 56] ^ Y[i + 65] ^ Y[i + 69] ^ Y[i + 79] ^ Y[i + 96] ^ Y[i + 101] ^ Y[i + 92] ^ (Y[i + 109] & Y[i + 101]) ^ (Y[i + 69] & Y[i + 65]) ^ (Y[i + 28] & Y[i + 13]) ^ (Y[i + 101] & Y[i + 96] & Y[i + 79]) ^ (Y[i + 65] & Y[i + 56] & Y[i + 37]) ^ (Y[i + 109] & Y[i + 79] & Y[i + 56] & Y[i + 13]) ^ (Y[i + 101] & Y[i + 96] & Y[i + 69] & Y[i + 65]) ^ (Y[i + 109] & Y[i + 101] & Y[i + 37] & Y[i + 28]) ^ (Y[i + 109] & Y[i + 101] & Y[i + 96] & Y[i + 79] & Y[i + 69]) ^ (Y[i + 65] & Y[i + 56] & Y[i + 37] & Y[i + 28] & Y[i + 13]) ^ (Y[i + 96] & Y[i + 79] & Y[i + 69] & Y[i + 65] & Y[i + 56] & Y[i + 37]);
|
||||
|
||||
/* need L[i] as linear term only, for invertibility */
|
||||
L[L_LEN_S + i] = L[i];
|
||||
L[L_LEN_S + i] ^= L[i + 3]; // linear feedback here
|
||||
|
||||
/* compute output of the h function */
|
||||
h = X[i + 47] ^ Y[i + 111] ^ (Y[i + 8] & X[i + 100]) ^ (X[i + 72] & X[i + 100]) ^ (X[i + 100] & Y[i + 111]) ^ (Y[i + 8] & X[i + 47] & X[i + 72]) ^ (Y[i + 8] & X[i + 72] & X[i + 100]) ^ (Y[i + 8] & X[i + 72] & Y[i + 111]) ^ (X[i + 47] & X[i + 72] & Y[i + 111] & L[i]) ^ (X[i + 47] & L[i]);
|
||||
h ^= X[i + 1] ^ Y[i + 3] ^ X[i + 7] ^ Y[i + 18] ^ X[i + 58] ^ Y[i + 80] ^ X[i + 105] ^ L[i];
|
||||
h ^= Y[i + 34] ^ Y[i + 71] ^ X[i + 90] ^ Y[i + 91];
|
||||
|
||||
/* feedback of h into the registers */
|
||||
X[N_LEN_S + i] ^= h;
|
||||
Y[N_LEN_S + i] ^= h;
|
||||
}
|
||||
|
||||
/* copy final state into hashState */
|
||||
for (i = 0; i < N_LEN_S; ++i) {
|
||||
x[i] = X[ROUNDS_S + i];
|
||||
x[i + N_LEN_S] = Y[ROUNDS_S + i];
|
||||
}
|
||||
|
||||
free(X);
|
||||
free(Y);
|
||||
free(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int permute_c(u32 *x) {
|
||||
/* state of 384=2x192 bits */
|
||||
#define ROUNDS_C 2 * 384
|
||||
#define N_LEN_C 192
|
||||
#define L_LEN_C 16
|
||||
|
||||
u32 *X, *Y, *L;
|
||||
u32 h;
|
||||
int i;
|
||||
|
||||
X = (u32 *)malloc((N_LEN_C + ROUNDS_C) * sizeof(u32));
|
||||
Y = (u32 *)malloc((N_LEN_C + ROUNDS_C) * sizeof(u32));
|
||||
L = (u32 *)malloc((L_LEN_C + ROUNDS_C) * sizeof(u32));
|
||||
|
||||
/* local copy of the state in the registers*/
|
||||
for (i = 0; i < N_LEN_C; ++i) {
|
||||
X[i] = x[i];
|
||||
Y[i] = x[i + N_LEN_C];
|
||||
}
|
||||
|
||||
/* initialize the LFSR to 11..11 */
|
||||
for (i = 0; i < L_LEN_C; ++i)
|
||||
L[i] = 0xFFFFFFFF;
|
||||
|
||||
/* iterate rounds */
|
||||
for (i = 0; i < ROUNDS_C; ++i) {
|
||||
|
||||
X[N_LEN_C + i] = X[i] ^ Y[i];
|
||||
X[N_LEN_C + i] ^= X[i + 13] ^ X[i + 34] ^ X[i + 65] ^ X[i + 77] ^ X[i + 94] ^ X[i + 109] ^ X[i + 127] ^ X[i + 145] ^ X[i + 157] ^ X[i + 140] ^ (X[i + 159] & X[i + 157]) ^ (X[i + 109] & X[i + 94]) ^ (X[i + 47] & X[i + 13]) ^ (X[i + 157] & X[i + 145] & X[i + 127]) ^ (X[i + 94] & X[i + 77] & X[i + 65]) ^ (X[i + 159] & X[i + 127] & X[i + 77] & X[i + 13]) ^ (X[i + 157] & X[i + 145] & X[i + 109] & X[i + 94]) ^ (X[i + 159] & X[i + 157] & X[i + 65] & X[i + 47]) ^ (X[i + 159] & X[i + 157] & X[i + 145] & X[i + 127] & X[i + 109]) ^ (X[i + 94] & X[i + 77] & X[i + 65] & X[i + 47] & X[i + 13]) ^ (X[i + 145] & X[i + 127] & X[i + 109] & X[i + 94] & X[i + 77] & X[i + 65]);
|
||||
|
||||
Y[N_LEN_C + i] = Y[i];
|
||||
Y[N_LEN_C + i] ^= Y[i + 21] ^ Y[i + 57] ^ Y[i + 60] ^ Y[i + 94] ^ Y[i + 112] ^ Y[i + 125] ^ Y[i + 133] ^ Y[i + 152] ^ Y[i + 157] ^ Y[i + 146] ^ (Y[i + 159] & Y[i + 157]) ^ (Y[i + 125] & Y[i + 112]) ^ (Y[i + 36] & Y[i + 21]) ^ (Y[i + 157] & Y[i + 152] & Y[i + 133]) ^ (Y[i + 112] & Y[i + 94] & Y[i + 60]) ^ (Y[i + 159] & Y[i + 133] & Y[i + 94] & Y[i + 21]) ^ (Y[i + 157] & Y[i + 152] & Y[i + 125] & Y[i + 112]) ^ (Y[i + 159] & Y[i + 157] & Y[i + 60] & Y[i + 36]) ^ (Y[i + 159] & Y[i + 157] & Y[i + 152] & Y[i + 133] & Y[i + 125]) ^ (Y[i + 112] & Y[i + 94] & Y[i + 60] & Y[i + 36] & Y[i + 21]) ^ (Y[i + 152] & Y[i + 133] & Y[i + 125] & Y[i + 112] & Y[i + 94] & Y[i + 60]);
|
||||
|
||||
L[L_LEN_C + i] = L[i] ^ L[i + 2] ^ L[i + 3] ^ L[i + 5];
|
||||
|
||||
|
||||
h = X[i + 25] ^ Y[i + 59] ^ (Y[i + 3] & X[i + 55]) ^ (X[i + 46] & X[i + 55]) ^ (X[i + 55] & Y[i + 59]) ^ (Y[i + 3] & X[i + 25] & X[i + 46]) ^ (Y[i + 3] & X[i + 46] & X[i + 55]) ^ (Y[i + 3] & X[i + 46] & Y[i + 59]) ^ (X[i + 25] & X[i + 46] & Y[i + 59] & L[i]) ^ (X[i + 25] & L[i]);
|
||||
h ^= L[i];
|
||||
h ^= X[i + 4] ^ X[i + 28] ^ X[i + 40] ^ X[i + 85] ^ X[i + 112] ^ X[i + 141] ^ X[i + 146] ^ X[i + 152];
|
||||
h ^= Y[i + 2] ^ Y[i + 33] ^ Y[i + 60] ^ Y[i + 62] ^ Y[i + 87] ^ Y[i + 99] ^ Y[i + 138] ^ Y[i + 148];
|
||||
|
||||
X[N_LEN_C + i] ^= h;
|
||||
Y[N_LEN_C + i] ^= h;
|
||||
}
|
||||
|
||||
/* copy final state into hashState */
|
||||
for (i = 0; i < N_LEN_C; ++i) {
|
||||
x[i] = X[ROUNDS_C + i];
|
||||
x[i + N_LEN_C] = Y[ROUNDS_C + i];
|
||||
}
|
||||
|
||||
free(X);
|
||||
free(Y);
|
||||
free(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* permutation of the state */
|
||||
static void permute(u32 *x) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("enter permute\n");
|
||||
showstate(x);
|
||||
#endif
|
||||
|
||||
#if defined(UQUARK)
|
||||
permute_u(x);
|
||||
#elif defined(DQUARK)
|
||||
permute_d(x);
|
||||
#elif defined(SQUARK)
|
||||
permute_s(x);
|
||||
#elif defined(CQUARK)
|
||||
permute_c(x);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("permute done\n");
|
||||
showstate(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* initialization of the IV */
|
||||
int init_iv(hashState *state) {
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("enter init\n");
|
||||
#endif
|
||||
|
||||
/* initialize state */
|
||||
for (i = 0; i < 8 * WIDTH; ++i)
|
||||
state->x[i] = (iv[i / 8] >> (7 - (i % 8))) & 1;
|
||||
|
||||
state->pos = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("init done\n");
|
||||
showstate(state->x);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int update(hashState *state, const u8 *data, int databytelen) {
|
||||
/* caller promises us that previous data had integral number of bytes */
|
||||
/* so state->pos is a multiple of 8 */
|
||||
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("enter update\n");
|
||||
#endif
|
||||
|
||||
while (databytelen > 0) {
|
||||
|
||||
/* get next byte */
|
||||
u8 u = *data;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("get byte %02x at pos %d\n", u, state->pos);
|
||||
#endif
|
||||
|
||||
/* xor state with each bit */
|
||||
for (i = 8 * state->pos; i < 8 * state->pos + 8; ++i) {
|
||||
state->x[(8 * (WIDTH - RATE)) + i] ^= (u >> (i % 8)) & 1;
|
||||
}
|
||||
|
||||
|
||||
data += 1;
|
||||
databytelen -= 1;
|
||||
state->pos += 1;
|
||||
|
||||
if (state->pos == RATE) {
|
||||
permute(state->x);
|
||||
state->pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("update done\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* finalize (padding) and return digest */
|
||||
int final(hashState *state, u8 *out) {
|
||||
int i;
|
||||
int outbytes = 0;
|
||||
u8 u;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("enter final\n");
|
||||
#endif
|
||||
|
||||
/* append '1' bit */
|
||||
state->x[8 * (WIDTH - RATE) + state->pos * 8] ^= 1;
|
||||
|
||||
/* permute to obtain first final state*/
|
||||
permute(state->x);
|
||||
|
||||
/* zeroize output buffer */
|
||||
for (i = 0; i < DIGEST; ++i)
|
||||
out[i] = 0;
|
||||
|
||||
/* while output requested, extract RATE bytes and permute */
|
||||
while (outbytes < DIGEST) {
|
||||
|
||||
/* extract one byte */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
u = state->x[8 * (WIDTH - RATE) + i + 8 * (outbytes % RATE)] & 1;
|
||||
out[outbytes] ^= (u << (7 - i));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("extracted byte %02x (%d)\n", out[outbytes], outbytes);
|
||||
#endif
|
||||
|
||||
outbytes += 1;
|
||||
|
||||
if (outbytes == DIGEST)
|
||||
break;
|
||||
|
||||
/* if RATE bytes extracted, permute again */
|
||||
if (!(outbytes % RATE)) {
|
||||
permute(state->x);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("final done\n");
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int quark(u8 *out, u8 *in, u64 inlen) {
|
||||
/* inlen in bytes */
|
||||
|
||||
hashState state;
|
||||
|
||||
init_iv(&state);
|
||||
update(&state, in, inlen);
|
||||
final(&state, out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
USBvalve
|
||||
*/
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint8_t u8;
|
||||
|
||||
#define CQUARK
|
||||
|
||||
#if defined(UQUARK)
|
||||
#define CAPACITY 16
|
||||
#define RATE 1
|
||||
#define WIDTH 17
|
||||
#elif defined(DQUARK)
|
||||
#define CAPACITY 20
|
||||
#define RATE 2
|
||||
#define WIDTH 22
|
||||
#elif defined(SQUARK)
|
||||
#define CAPACITY 28
|
||||
#define RATE 4
|
||||
#define WIDTH 32
|
||||
#elif defined(CQUARK)
|
||||
#define CAPACITY 40
|
||||
#define RATE 8
|
||||
#define WIDTH 48
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int quark(u8 *out, u8 *in, u64 inlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -37,6 +37,8 @@
|
||||
// README.TXT
|
||||
// System Volume Information
|
||||
//
|
||||
// Files information are saved at Block 7
|
||||
//
|
||||
|
||||
// Keep 11 chars
|
||||
#define DISK_LABEL 'M', 'y', 'D', 'r', 'i', 'v', 'e', ' ', ' ', ' ', ' '
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 170 KiB |
Reference in New Issue
Block a user