mirror of
https://github.com/cecio/USBvalve.git
synced 2026-03-09 02:41:59 +00:00
- general clock speed lowered to 120Mhz and managed manually on core1 to achieve max compatibility for HID
- hashing moved to XxHash for performance reason - bump to release 0.13.0 - upgrade board to `Raspberry Pi RP2040 (3.4.1)`
This commit is contained in:
@@ -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
|
||||
@@ -42,7 +44,7 @@ Adafruit_USBH_Host USBHost;
|
||||
// Define vars for OLED screen
|
||||
#define I2C_ADDRESS 0x3C // 0X3C+SA0 - 0x3C or 0x3D
|
||||
#define RST_PIN -1 // Define proper RST_PIN if required.
|
||||
#define OLED_HEIGHT 64 // 64 or 32 depending on the OLED
|
||||
#define OLED_HEIGHT 32 // 64 or 32 depending on the OLED
|
||||
#define OLED_LINES (OLED_HEIGHT / 8)
|
||||
SSD1306AsciiWire oled;
|
||||
|
||||
@@ -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,7 +75,7 @@ bool activeState = false;
|
||||
//
|
||||
// USBvalve globals
|
||||
//
|
||||
#define VERSION "USBvalve - 0.12.3"
|
||||
#define VERSION "USBvalve - 0.13.0"
|
||||
boolean readme = false;
|
||||
boolean autorun = false;
|
||||
boolean written = false;
|
||||
@@ -110,16 +111,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 +122,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 +166,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 +185,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;
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user