add lz4 to arm side

This commit is contained in:
slurdge 2020-06-05 16:24:05 +02:00
commit 1a8eff5d42
5 changed files with 78 additions and 79 deletions

View file

@ -75,13 +75,13 @@ include Standalone/Makefile.inc
#the FPGA bitstream files. Note: order matters! #the FPGA bitstream files. Note: order matters!
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
#the zlib source files required for decompressing the fpga config at run time #the lz4 source files required for decompressing the fpga config at run time
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c SRC_LZ4 = lz4.c
#additional defines required to compile zlib #additional defines required to compile lz4
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED LZ4_CFLAGS = -DNEED_MEMMOVE -DLZ4_MEMORY_USAGE=8
APP_CFLAGS += $(ZLIB_CFLAGS) APP_CFLAGS += $(LZ4_CFLAGS)
# zlib includes: # lz4 includes:
APP_CFLAGS += -I../common/zlib APP_CFLAGS += -I../common/lz4
# stdint.h provided locally until GCC 4.5 becomes C99 compliant, # stdint.h provided locally until GCC 4.5 becomes C99 compliant,
# stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc
@ -93,7 +93,7 @@ THUMBSRC = start.c \
$(SRC_ISO15693) \ $(SRC_ISO15693) \
$(SRC_NFCBARCODE) \ $(SRC_NFCBARCODE) \
$(SRC_LF) \ $(SRC_LF) \
$(SRC_ZLIB) \ $(SRC_LZ4) \
$(SRC_LEGIC) \ $(SRC_LEGIC) \
$(SRC_FLASH) \ $(SRC_FLASH) \
$(SRC_SMARTCARD) \ $(SRC_SMARTCARD) \

View file

@ -17,10 +17,19 @@
#include "ticks.h" #include "ticks.h"
#include "dbprint.h" #include "dbprint.h"
#include "util.h" #include "util.h"
#include "zlib.h"
#include "fpga.h" #include "fpga.h"
#include "string.h" #include "string.h"
#include "lz4.h" // uncompress
typedef struct lz4_stream_s {
LZ4_streamDecode_t* lz4StreamDecode;
char * next_in;
int avail_in;
} lz4_stream;
typedef lz4_stream* lz4_streamp;
// remember which version of the bitstream we have already downloaded to the FPGA // remember which version of the bitstream we have already downloaded to the FPGA
static int downloaded_bitstream = 0; static int downloaded_bitstream = 0;
@ -30,8 +39,6 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
static uint8_t *fpga_image_ptr = NULL; static uint8_t *fpga_image_ptr = NULL;
static uint32_t uncompressed_bytes_cnt; static uint32_t uncompressed_bytes_cnt;
#define OUTPUT_BUFFER_LEN 80
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Set up the Serial Peripheral Interface as master // Set up the Serial Peripheral Interface as master
// Used to write the FPGA config word // Used to write the FPGA config word
@ -180,18 +187,25 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with // Uncompress (inflate) the FPGA data. Returns one decompressed byte with
// each call. // each call.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_combined_stream(lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
fpga_image_ptr = output_buffer; fpga_image_ptr = output_buffer;
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH); int cmp_bytes = *(compressed_fpga_stream->next_in + 3);
cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+2);
if (res != Z_OK) cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+1);
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg); cmp_bytes = (cmp_bytes << 8) + *(compressed_fpga_stream->next_in+0);
compressed_fpga_stream->next_in += 4;
if (res < 0) compressed_fpga_stream->avail_in -= cmp_bytes + 4;
int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode,
compressed_fpga_stream->next_in,
(char*)output_buffer,
cmp_bytes,
FPGA_RING_BUFFER_BYTES);
if (res <= 0) {
Dbprintf("inflate returned: %d", res);
return res; return res;
}
compressed_fpga_stream->next_in += cmp_bytes;
} }
uncompressed_bytes_cnt++; uncompressed_bytes_cnt++;
return *fpga_image_ptr++; return *fpga_image_ptr++;
@ -202,7 +216,7 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
// are combined into one big file: // are combined into one big file:
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) { while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != (bitstream_version - 1)) {
// skip undesired data belonging to other bitstream_versions // skip undesired data belonging to other bitstream_versions
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
@ -211,37 +225,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
} }
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) {
return BigBuf_malloc(items * size);
}
// free eventually allocated BigBuf memory
static void fpga_inflate_free(voidpf opaque, voidpf address) {
BigBuf_free();
BigBuf_Clear_ext(false);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Initialize decompression of the respective (HF or LF) FPGA stream // Initialize decompression of the respective (HF or LF) FPGA stream
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static bool reset_fpga_stream(int bitstream_version, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
uncompressed_bytes_cnt = 0; uncompressed_bytes_cnt = 0;
// initialize z_stream structure for inflate: // initialize z_stream structure for inflate:
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->next_in = (char*)&_binary_obj_fpga_all_bit_z_start;
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start; compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
compressed_fpga_stream->zalloc = &fpga_inflate_malloc; if (res == 0)
compressed_fpga_stream->zfree = &fpga_inflate_free;
int res = inflateInit2(compressed_fpga_stream, 0);
if (res < 0)
return false; return false;
fpga_image_ptr = output_buffer; fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES;
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
@ -266,7 +266,7 @@ static void DownloadFPGA_byte(uint8_t w) {
} }
// Download the fpga image starting at current stream position with length FpgaImageLen bytes // Download the fpga image starting at current stream position with length FpgaImageLen bytes
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static void DownloadFPGA(int bitstream_version, int FpgaImageLen, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
int i = 0; int i = 0;
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
@ -348,7 +348,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes * (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
* length. * length.
*/ */
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, lz4_streamp compressed_fpga_stream, uint8_t *output_buffer) {
int result = 0; int result = 0;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
uint16_t numbytes = 0; uint16_t numbytes = 0;
@ -407,8 +407,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
// Send waiting time extension request as this will take a while // Send waiting time extension request as this will take a while
send_wtx(1500); send_wtx(1500);
z_stream compressed_fpga_stream;
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
bool verbose = (DBGLEVEL > 3); bool verbose = (DBGLEVEL > 3);
@ -416,6 +414,11 @@ void FpgaDownloadAndGo(int bitstream_version) {
BigBuf_free(); BigBuf_free();
BigBuf_Clear_ext(verbose); BigBuf_Clear_ext(verbose);
lz4_stream compressed_fpga_stream;
LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
uint8_t * output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
return; return;
@ -425,8 +428,6 @@ void FpgaDownloadAndGo(int bitstream_version) {
downloaded_bitstream = bitstream_version; downloaded_bitstream = bitstream_version;
} }
inflateEnd(&compressed_fpga_stream);
// turn off antenna // turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -14,49 +14,28 @@
#include "proxmark3_arm.h" #include "proxmark3_arm.h"
#include "appmain.h" #include "appmain.h"
#include "zlib.h" #include "lz4.h"
#include "BigBuf.h" #include "BigBuf.h"
static uint8_t *next_free_memory; static uint8_t *next_free_memory;
extern struct common_area common_area; extern struct common_area common_area;
extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__; extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __bss_end__;
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) {
uint8_t *allocated_memory;
allocated_memory = next_free_memory;
next_free_memory += items * size;
return allocated_memory;
}
static void inflate_free(voidpf opaque, voidpf address) {
// nothing to do
}
static void uncompress_data_section(void) { static void uncompress_data_section(void) {
z_stream data_section;
next_free_memory = BigBuf_get_addr(); next_free_memory = BigBuf_get_addr();
// initialize zstream structure int avail_in = *(&__data_start__ + 3);
data_section.next_in = (uint8_t *) &__data_src_start__; avail_in = (avail_in << 8) + *(&__data_start__+2);
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter. avail_in = (avail_in << 8) + *(&__data_start__+1);
data_section.next_out = (uint8_t *) &__data_start__; avail_in = (avail_in << 8) + *(&__data_start__+0); // compressed size. Correct.
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct. int avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
data_section.zalloc = &inflate_malloc; // uncompress data segment to RAM
data_section.zfree = &inflate_free; int res = LZ4_decompress_safe(&__data_src_start__ + 4, &__data_start__, avail_in, avail_out);
data_section.opaque = NULL;
// initialize zlib for inflate
int res = inflateInit2(&data_section, 15);
if (res < 0) if (res < 0)
return; return;
// uncompress data segment to RAM
inflate(&data_section, Z_FINISH);
// save the size of the compressed data section // save the size of the compressed data section
common_area.arg1 = data_section.total_in; common_area.arg1 = res;
} }
void __attribute__((section(".startos"))) Vector(void); void __attribute__((section(".startos"))) Vector(void);

View file

@ -182,6 +182,25 @@
#include <string.h> /* memset, memcpy */ #include <string.h> /* memset, memcpy */
#define MEM_INIT(p,v,s) memset((p),(v),(s)) #define MEM_INIT(p,v,s) memset((p),(v),(s))
#ifdef NEED_MEMMOVE
void *
memmove (void *dest, const void *src, size_t len)
{
char *d = dest;
const char *s = src;
if (d < s)
while (len--)
*d++ = *s++;
else
{
char *lasts = (char*)s + (len-1);
char *lastd = d + (len-1);
while (len--)
*lastd-- = *lasts--;
}
return dest;
}
#endif
/*-************************************ /*-************************************
* Common Constants * Common Constants

View file

@ -35,7 +35,7 @@ OBJDIR = obj
INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I. INCLUDE = -I../include -I../common_arm -I../common_fpga -I../common -I.
# Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory
VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/zlib ../fpga ../armsrc/Standalone VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/lz4 ../fpga ../armsrc/Standalone
INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h