From 5e532c93674b65d7a0f024b113820e3738a0bebe Mon Sep 17 00:00:00 2001 From: Fabian Druschke Date: Tue, 19 Mar 2024 08:24:38 -0300 Subject: [PATCH 1/5] Rebased branch, fixed conflicts. Now Xoroshiro-256 in standalone branch --- src/Makefile.am | 2 +- src/gui.c | 65 ++++++++++++++++++++++++++++++-- src/options.c | 12 ++++++ src/prng.c | 46 +++++++++++++++++++++++ src/prng.h | 7 ++++ src/xor/xoroshiro256_prng.c | 74 +++++++++++++++++++++++++++++++++++++ src/xor/xoroshiro256_prng.h | 44 ++++++++++++++++++++++ 7 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 src/xor/xoroshiro256_prng.c create mode 100644 src/xor/xoroshiro256_prng.h diff --git a/src/Makefile.am b/src/Makefile.am index 7d9bb44..6dec022 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ AM_LDFLAGS = # this lists the binaries to produce, the (non-PHONY, binary) targets in # the previous manual Makefile bin_PROGRAMS = nwipe -nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c hddtemp_scsi/hddtemp.h hddtemp_scsi/scsi.h hddtemp_scsi/scsicmds.h hddtemp_scsi/get_scsi_temp.c hddtemp_scsi/scsi.c hddtemp_scsi/scsicmds.c +nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h xor/xoroshiro256_prng.h xor/xoroshiro256_prng.c pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c hddtemp_scsi/hddtemp.h hddtemp_scsi/scsi.h hddtemp_scsi/scsicmds.h hddtemp_scsi/get_scsi_temp.c hddtemp_scsi/scsi.c hddtemp_scsi/scsicmds.c nwipe_LDADD = $(PARTED_LIBS) $(LIBCONFIG) diff --git a/src/gui.c b/src/gui.c index 9c34910..609be69 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1599,10 +1599,13 @@ void nwipe_gui_prng( void ) extern nwipe_prng_t nwipe_twister; extern nwipe_prng_t nwipe_isaac; extern nwipe_prng_t nwipe_isaac64; + extern nwipe_prng_t nwipe_aes_ctr_prng; + extern nwipe_prng_t nwipe_xoroshiro256_prng; + extern int terminate_signal; /* The number of implemented PRNGs. */ - const int count = 3; + const int count = 4; /* The first tabstop. */ const int tab1 = 2; @@ -1636,7 +1639,10 @@ void nwipe_gui_prng( void ) { focus = 2; } - + if( nwipe_options.prng == &nwipe_xoroshiro256_prng ) + { + focus = 3; + } do { /* Clear the main window. */ @@ -1651,6 +1657,7 @@ void nwipe_gui_prng( void ) mvwprintw( main_window, yy++, tab1, " %s", nwipe_twister.label ); mvwprintw( main_window, yy++, tab1, " %s", nwipe_isaac.label ); mvwprintw( main_window, yy++, tab1, " %s", nwipe_isaac64.label ); + mvwprintw( main_window, yy++, tab1, " %s", nwipe_xoroshiro256_prng.label ); yy++; /* Print the cursor. */ @@ -1734,7 +1741,55 @@ void nwipe_gui_prng( void ) "Performs best on a 64-bit CPU. Use ISAAC if this system has a 32-bit CPU. " ); break; - } /* switch */ + case 3: + mvwprintw( main_window, + yy++, + tab1, + "Xoroshiro256**, originally designed by David Blackman and Sebastiano Vigna" ); + mvwprintw( main_window, + yy++, + tab1, + "for 128 bits, was adapted to 256 bits by Fabian Druschke. This adaptation " ); + mvwprintw( main_window, + yy++, + tab1, + "enhances its capability for fast, high-quality generation of pseudo-random " ); + mvwprintw( main_window, + yy++, + tab1, + "numbers with a state size of 256 bits. It boasts an extremely long period " ); + mvwprintw( main_window, + yy++, + tab1, + "of 2^256-1 without sacrificing performance, suitable for a wide range of " ); + mvwprintw( main_window, + yy++, + tab1, + "applications. " ); + mvwprintw( main_window, + yy++, + tab1, + " " ); + mvwprintw( main_window, + yy++, + tab1, + "The simple arithmetic operations (shifts, rotations, and XORs) of " ); + mvwprintw( main_window, + yy++, + tab1, + "Xoroshiro256** ensure low computational complexity. This, combined with " ); + mvwprintw( main_window, + yy++, + tab1, + "the adaptation for 256 bits by Fabian Druschke, allows efficient use " ); + mvwprintw( main_window, + yy++, + tab1, + "especially for legacy systems, due to its efficiency and minimal demands. " ); + break; + } + + /* switch */ /* Add a border. */ box( main_window, 0, 0 ); @@ -1794,6 +1849,10 @@ void nwipe_gui_prng( void ) { nwipe_options.prng = &nwipe_isaac64; } + if( focus == 3 ) + { + nwipe_options.prng = &nwipe_xoroshiro256_prng; + } return; case KEY_BACKSPACE: diff --git a/src/options.c b/src/options.c index 95050db..a1e99dc 100644 --- a/src/options.c +++ b/src/options.c @@ -42,6 +42,7 @@ int nwipe_options_parse( int argc, char** argv ) extern nwipe_prng_t nwipe_twister; extern nwipe_prng_t nwipe_isaac; extern nwipe_prng_t nwipe_isaac64; + extern nwipe_prng_t nwipe_xoroshiro256_prng; /* The getopt() result holder. */ int nwipe_opt; @@ -490,6 +491,11 @@ int nwipe_options_parse( int argc, char** argv ) nwipe_options.prng = &nwipe_isaac64; break; } + if( strcmp( optarg, "xoroshiro256_prng" ) == 0 ) + { + nwipe_options.prng = &nwipe_xoroshiro256_prng; + break; + } /* Else we do not know this PRNG. */ fprintf( stderr, "Error: Unknown prng '%s'.\n", optarg ); @@ -539,6 +545,7 @@ void nwipe_options_log( void ) extern nwipe_prng_t nwipe_twister; extern nwipe_prng_t nwipe_isaac; extern nwipe_prng_t nwipe_isaac64; + extern nwipe_prng_t nwipe_xoroshiro256_prng; /** * Prints a manifest of options to the log. @@ -590,6 +597,11 @@ void nwipe_options_log( void ) { nwipe_log( NWIPE_LOG_NOTICE, " prng = Mersenne Twister" ); } + if( nwipe_options.prng == &nwipe_xoroshiro256_prng ) + { + nwipe_log( NWIPE_LOG_NOTICE, " prng = XORoshiro-256 (EXPERIMENTAL!)" ); + } + else { if( nwipe_options.prng == &nwipe_isaac ) diff --git a/src/prng.c b/src/prng.c index 45c6cb7..3845606 100644 --- a/src/prng.c +++ b/src/prng.c @@ -25,12 +25,16 @@ #include "mt19937ar-cok/mt19937ar-cok.h" #include "isaac_rand/isaac_rand.h" #include "isaac_rand/isaac64.h" +#include "xor/xoroshiro256_prng.h" //XORoshiro-256 prototype nwipe_prng_t nwipe_twister = { "Mersenne Twister (mt19937ar-cok)", nwipe_twister_init, nwipe_twister_read }; nwipe_prng_t nwipe_isaac = { "ISAAC (rand.c 20010626)", nwipe_isaac_init, nwipe_isaac_read }; nwipe_prng_t nwipe_isaac64 = { "ISAAC-64 (isaac64.c)", nwipe_isaac64_init, nwipe_isaac64_read }; +/* AES-CTR-NI PRNG Structure */ +nwipe_prng_t nwipe_xoroshiro256_prng = { "XORoshiro-256", nwipe_xoroshiro256_prng_init, nwipe_xoroshiro256_prng_read }; + /* Print given number of bytes from unsigned integer number to a byte stream buffer starting with low-endian. */ static inline void u32_to_buffer( u8* restrict buffer, u32 val, const int len ) { @@ -250,3 +254,45 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE ) return 0; } + +/* EXPERIMENTAL implementation of XORoroshiro256 algorithm to provide high-quality, but a lot of random numbers */ + +int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE ) +{ + nwipe_log( NWIPE_LOG_NOTICE, "Initialising XORoroshiro-256 PRNG" ); + + if( *state == NULL ) + { + /* This is the first time that we have been called. */ + *state = malloc( sizeof( xoroshiro256_state_t ) ); + } + xoroshiro256_init( + (xoroshiro256_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) ); + + return 0; +} + +int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE ) +{ + u8* restrict bufpos = buffer; + size_t words = count / SIZE_OF_XOROSHIRO256_PRNG; + + /* Loop to fill the buffer with blocks directly from the XORoroshiro256 algorithm */ + for( size_t ii = 0; ii < words; ++ii ) + { + xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, bufpos ); + bufpos += SIZE_OF_XOROSHIRO256_PRNG; // Move to the next block + } + + /* Handle remaining bytes if count is not a multiple of SIZE_OF_XOROSHIRO256_PRNG */ + const size_t remain = count % SIZE_OF_XOROSHIRO256_PRNG; + if( remain > 0 ) + { + unsigned char temp_output[16]; // Temporary buffer for the last block + xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, temp_output ); + // Copy the remaining bytes + memcpy( bufpos, temp_output, remain ); + } + + return 0; // Success +} diff --git a/src/prng.h b/src/prng.h index 8dfa3d7..5433b1c 100644 --- a/src/prng.h +++ b/src/prng.h @@ -55,6 +55,10 @@ int nwipe_isaac_read( NWIPE_PRNG_READ_SIGNATURE ); int nwipe_isaac64_init( NWIPE_PRNG_INIT_SIGNATURE ); int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE ); +/* AES-CTR-NI prototypes. */ +int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE ); +int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE ); + /* Size of the twister is not derived from the architecture, but it is strictly 4 bytes */ #define SIZE_OF_TWISTER 4 @@ -62,4 +66,7 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE ); #define SIZE_OF_ISAAC 4 #define SIZE_OF_ISAAC64 8 +/* Size of the XOROSHIRO-256 is not derived from the architecture, but it is strictly 32 bytes */ +#define SIZE_OF_XOROSHIRO256_PRNG 32 + #endif /* PRNG_H_ */ diff --git a/src/xor/xoroshiro256_prng.c b/src/xor/xoroshiro256_prng.c new file mode 100644 index 0000000..defef88 --- /dev/null +++ b/src/xor/xoroshiro256_prng.c @@ -0,0 +1,74 @@ +/* + * XORoshiro-256 PRNG Implementation + * Author: Fabian Druschke + * Date: 2024-03-13 + * + * This is a XORoshiro-256 (XOR/rotate/shift/rotate) pseudorandom number generator + * implementation, designed for fast and efficient generation of high-quality + * pseudorandom numbers. XORoshiro-256 is part of the XORoshiro family of PRNGs known + * for their simplicity and excellent statistical properties for a wide range of + * applications, though they are not suitable for cryptographic purposes due to their + * predictability. + * + * As the author of this implementation, I, Fabian Druschke, hereby release this work into + * the public domain. I dedicate any and all copyright interest in this work to the public + * domain, making it free to use for anyone for any purpose without any conditions, unless + * such conditions are required by law. + * + * This software is provided "as is", without warranty of any kind, express or implied, + * including but not limited to the warranties of merchantability, fitness for a particular + * purpose, and noninfringement. In no event shall the authors be liable for any claim, + * damages, or other liability, whether in an action of contract, tort, or otherwise, arising + * from, out of, or in connection with the software or the use or other dealings in the software. + * + * Note: This implementation does not utilize OpenSSL or any cryptographic libraries, as + * XORoshiro-256 is not intended for cryptographic applications. It is crucial for applications + * requiring cryptographic security to use a cryptographically secure PRNG. + */ + +#include "xoroshiro256_prng.h" +#include +#include + +void xoroshiro256_init( xoroshiro256_state_t* state, uint64_t init_key[], unsigned long key_length ) +{ + // Initialization logic; ensure 256 bits are properly seeded + for( int i = 0; i < 4; i++ ) + { + if( i < key_length ) + { + state->s[i] = init_key[i]; + } + else + { + // Example fallback for insufficient seeds; consider better seeding strategies + state->s[i] = state->s[i - 1] * 6364136223846793005ULL + 1; + } + } +} + +static inline uint64_t rotl( const uint64_t x, int k ) +{ + return ( x << k ) | ( x >> ( 64 - k ) ); +} + +void xoroshiro256_genrand_uint256_to_buf( xoroshiro256_state_t* state, unsigned char* bufpos ) +{ + // This part of the code updates the state using xoroshiro256**'s algorithm. + const uint64_t result_starstar = rotl( state->s[1] * 5, 7 ) * 9; + const uint64_t t = state->s[1] << 17; + + state->s[2] ^= state->s[0]; + state->s[3] ^= state->s[1]; + state->s[1] ^= state->s[2]; + state->s[0] ^= state->s[3]; + + state->s[2] ^= t; + state->s[3] = rotl( state->s[3], 45 ); + + // Note: 'result_starstar' was only used for demonstration purposes and is not part of the + // original Xoroshiro256** specification. Here, we write the complete state into the buffer. + // Ensure that 'bufpos' has enough storage space (256 bits / 32 bytes). + + memcpy( bufpos, state->s, 32 ); // Copies the entire 256-bit (32 bytes) state into 'bufpos' +} diff --git a/src/xor/xoroshiro256_prng.h b/src/xor/xoroshiro256_prng.h new file mode 100644 index 0000000..a7d9232 --- /dev/null +++ b/src/xor/xoroshiro256_prng.h @@ -0,0 +1,44 @@ +/* + * XORoshiro-256 PRNG Definitions + * Author: Fabian Druschke + * Date: 2024-03-13 + * + * This header file contains definitions for the XORoshiro-256 pseudorandom number generator + * (PRNG) implementation. XORoshiro-256 is part of the XORoshiro family of PRNGs, known for + * their simplicity, efficiency, and high-quality pseudorandom number generation suitable for + * a wide range of applications, excluding cryptographic purposes due to its predictable nature. + * + * As the author of this work, I, Fabian Druschke, hereby release this work into the public + * domain. I dedicate any and all copyright interest in this work to the public domain, making + * it free to use for anyone for any purpose without any conditions, unless such conditions are + * required by law. + * + * This software is provided "as is", without warranty of any kind, express or implied, + * including but not limited to the warranties of merchantability, fitness for a particular + * purpose, and noninfringement. In no event shall the authors be liable for any claim, + * damages, or other liability, whether in an action of contract, tort, or otherwise, arising + * from, out of, or in connection with the software or the use or other dealings in the software. + * + * Note: This implementation does not utilize any cryptographic libraries, as XORoshiro-256 is + * not intended for cryptographic applications. It is crucial for applications requiring + * cryptographic security to use a cryptographically secure PRNG. + */ + +#ifndef XOROSHIRO256_PRNG_H +#define XOROSHIRO256_PRNG_H + +#include + +// Structure to store the state of the xoroshiro256** random number generator +typedef struct xoroshiro256_state_s +{ + uint64_t s[4]; +} xoroshiro256_state_t; + +// Initializes the xoroshiro256** random number generator with a seed +void xoroshiro256_init( xoroshiro256_state_t* state, uint64_t init_key[], unsigned long key_length ); + +// Generates a 256-bit random number using xoroshiro256** and stores it directly in the output buffer +void xoroshiro256_genrand_uint256_to_buf( xoroshiro256_state_t* state, unsigned char* bufpos ); + +#endif // XOROSHIRO256_PRNG_H From 50bcf81ea60cfff40f3ec4d22c302705d28619c9 Mon Sep 17 00:00:00 2001 From: Fabian Druschke Date: Tue, 19 Mar 2024 08:25:09 -0300 Subject: [PATCH 2/5] Fixed src/temperature.c formatting --- src/temperature.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/temperature.c b/src/temperature.c index 19f9446..3f69e7b 100644 --- a/src/temperature.c +++ b/src/temperature.c @@ -16,8 +16,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -//#define _LARGEFILE64_SOURCE -//#define _FILE_OFFSET_BITS 64 +// #define _LARGEFILE64_SOURCE +// #define _FILE_OFFSET_BITS 64 #define _BSD_SOURCE #include From 87376a0bbb5ec481f722451d00cbd61dc9b31dbc Mon Sep 17 00:00:00 2001 From: Fabian Druschke Date: Wed, 20 Mar 2024 17:39:32 -0300 Subject: [PATCH 3/5] Removed leftover references to AES-CTR, not belonging here. --- src/prng.c | 2 +- src/prng.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prng.c b/src/prng.c index 3845606..d9fc407 100644 --- a/src/prng.c +++ b/src/prng.c @@ -32,7 +32,7 @@ nwipe_prng_t nwipe_twister = { "Mersenne Twister (mt19937ar-cok)", nwipe_twister nwipe_prng_t nwipe_isaac = { "ISAAC (rand.c 20010626)", nwipe_isaac_init, nwipe_isaac_read }; nwipe_prng_t nwipe_isaac64 = { "ISAAC-64 (isaac64.c)", nwipe_isaac64_init, nwipe_isaac64_read }; -/* AES-CTR-NI PRNG Structure */ +/* XOROSHIRO-256 PRNG Structure */ nwipe_prng_t nwipe_xoroshiro256_prng = { "XORoshiro-256", nwipe_xoroshiro256_prng_init, nwipe_xoroshiro256_prng_read }; /* Print given number of bytes from unsigned integer number to a byte stream buffer starting with low-endian. */ diff --git a/src/prng.h b/src/prng.h index 5433b1c..c48ee24 100644 --- a/src/prng.h +++ b/src/prng.h @@ -55,7 +55,7 @@ int nwipe_isaac_read( NWIPE_PRNG_READ_SIGNATURE ); int nwipe_isaac64_init( NWIPE_PRNG_INIT_SIGNATURE ); int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE ); -/* AES-CTR-NI prototypes. */ +/* XOROSHIRO-256 prototypes. */ int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE ); int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE ); From 4fad31ec50645c419f9e638c95113663514805a6 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 21 Mar 2024 22:03:24 +0000 Subject: [PATCH 4/5] Fix a couple of formatting issues in prng.c --- src/prng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prng.c b/src/prng.c index c0707e2..eaebabd 100644 --- a/src/prng.c +++ b/src/prng.c @@ -269,7 +269,7 @@ int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE ) *state = malloc( sizeof( add_lagg_fibonacci_state_t ) ); } add_lagg_fibonacci_init( - (add_lagg_fibonacci_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) ); + (add_lagg_fibonacci_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) ); return 0; } @@ -315,7 +315,7 @@ int nwipe_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE ) return 0; // Success } - + int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE ) { u8* restrict bufpos = buffer; From f66d838b2337761f68345b2fea8f6be026690b38 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 21 Mar 2024 22:07:52 +0000 Subject: [PATCH 5/5] Fix formatting in gui.c --- src/gui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui.c b/src/gui.c index 68aadd7..d30e4b0 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1746,9 +1746,9 @@ void nwipe_gui_prng( void ) tab1, "Performs best on a 64-bit CPU. Use ISAAC if this system has a 32-bit CPU. " ); break; - + case 3: - + mvwprintw( main_window, yy++, tab1,