73 Commits
v0.35 ... v0.37

Author SHA1 Message Date
PartialVolume
28271712db Update CHANGELOG.md 2024-05-10 20:08:28 +01:00
PartialVolume
ef312ff90d Merge pull request #577 from PartialVolume/change_nwipe.1_to_nwipe.8
Request change man/nwipe.1 to man/nwipe.8
2024-05-10 19:59:04 +01:00
PartialVolume
6d6b7ac8c1 Request change man/nwipe.1 to man/nwipe.8
Manpage is named nwipe.1 which would be correct but manpage
contains section 8 which forms a mismatch(warning) in Debian.

# Man sections
1   Executable programs or shell commands
2   System calls (functions provided by the kernel)
3   Library calls (functions within program libraries)
4   Special files (usually found in /dev)
5   File formats and conventions, e.g. /etc/passwd
6   Games
7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7), man-pages(7)
8   System administration commands (usually only for root)
9   Kernel routines [Non standard]

(requested by MvB)
2024-05-10 19:32:36 +01:00
PartialVolume
5140f92077 Merge pull request #576 from PartialVolume/master
Update CHANGELOG.md
2024-05-08 22:04:05 +01:00
PartialVolume
4893fa7ea0 Update CHANGELOG.md 2024-05-08 22:00:34 +01:00
PartialVolume
b83423a424 Merge pull request #575 from PartialVolume/bump_to_0.37
Bump to v0.37
2024-05-08 21:37:09 +01:00
PartialVolume
4394f24245 Bump to v0.37 2024-05-08 21:31:53 +01:00
PartialVolume
1ae76b5774 Merge pull request #574 from Polynomial-C/configure_ac_fix
configure.ac: Fix check for parted
2024-05-06 23:15:31 +01:00
Lars Wendler
fca8937f26 configure.ac: Fix check for parted
PKG_CHECK_MODULES needs all modules in a single list or else the following
error message appears during configure run:

  ./configure: 6807: libconfig: not found

because the macro interprets "[libconfig]" as the action that needs to be
done if parted was found.

Removed superfluous check for libconfig as requested by PartialVolume
2024-05-06 19:34:02 +02:00
PartialVolume
09d620c9c7 Update README.md
Update readme.md with the new prngs that will be available from V0.37+
2024-04-19 23:37:32 +01:00
Martijn van Brummelen
f0ed2fe7f0 Update nwipe.1
W: nwipe: wrong-manual-section 1 != 20 [usr/share/man/man1/nwipe.1.gz:1]
2024-04-16 20:11:10 +02:00
PartialVolume
9400ff5219 Merge pull request #571 from PartialVolume/Fix_conditional_jump_or_move_on_unitialised_value
Fix conditional jump on uninitialised value
2024-04-08 21:26:59 +01:00
PartialVolume
81fc479239 Fix conditional jump on unitialised value
This fixes a valgrind detected error. We check that
the number of real max sectors is greater than zero before
incrementing the value by 1. However ocassionaly the ioctl
call may not be able to obtain the dco and therefore the
ioctl data block is never populated. By zeroing the data
block prior to use and if it is not populated by the ioctl
call then the calculated real max sectors will be
zero and no increment will occur which is what we want.
2024-04-08 21:17:41 +01:00
PartialVolume
28095801ac Merge pull request #569 from AndCycle/fix_help
Add missing help for HMG IS5 enhanced
2024-04-05 12:14:54 +01:00
AndCycle
66a951722d Add missing help for HMG IS5 enhanced 2024-04-05 05:36:06 +08:00
PartialVolume
834348c8c8 Merge pull request #566 from Knogle/master
XORoshiro-256 and ALFG as default PRNG for 64-Bit and 32-Bit platforms. Also PRNG method as default method.
2024-03-28 22:09:22 +00:00
PartialVolume
e4a51c00c1 Merge pull request #565 from PartialVolume/Fix_valgrind_unconditional_jump_or_move_on_unitialised_value
Fix valgrind jump or move on unconditional value in nwipe config code
2024-03-28 17:38:21 +00:00
PartialVolume
00bcce475b Fix valgrind jump or move on unconditional 2024-03-28 17:17:19 +00:00
Fabian Druschke
0114ccf937 Fixed formatting using make format for options.c 2024-03-28 11:58:07 -03:00
Fabian Druschke
616a2ab236 Forgot nwipe_ in front of add_lagged_fibonacci, leading to compiling error 2024-03-28 11:56:54 -03:00
Fabian Druschke
e6e638c4dc Advocate for PRNG as default option, as well as XORoshiro-256 for 64-Bit systems, and Additive Lagged Fibonacci Generator for 32-Bit legacy systems 2024-03-28 11:51:47 -03:00
PartialVolume
8ad4fe200d Merge pull request #562 from Knogle/master
Fixed memory leak in line 328, writing 1 byte beyond allocated memory.
2024-03-26 21:39:28 +00:00
PartialVolume
a4ce92be6f Merge pull request #561 from PartialVolume/Update_pdf_with_xoro_and_fibonacci_prngs
Update PDF code with new PRNGs
2024-03-26 21:21:18 +00:00
PartialVolume
e851769025 Update PDF code with new PRNGs
Updated pdf to recognise XORshiro256 and
lagged Fibonacci PRNGs.
2024-03-26 21:17:23 +00:00
Fabian Druschke
c7ada53d4e Fixed memory leak in line 328, writing 1 byte beyond allocated memory. 2024-03-26 13:28:10 -03:00
PartialVolume
bb93793d7f Merge pull request #558 from Knogle/master
Renamed N and M to MT_STATE_SIZE and MT_MIDDLE_WORD due to const naming of mt19937ar-cok.h, causing conflicts with SHA-512 HMAC's libssl.
2024-03-22 01:35:17 +00:00
PartialVolume
ea386f35e7 Update gui.c with correct number of prngs 2024-03-21 22:51:31 +00:00
PartialVolume
204a82f6f0 Merge pull request #555 from Knogle/xoroshiro256
Implement XORoshiro-256 PRNG for Enhanced Random Number Generation Efficiency
2024-03-21 22:10:14 +00:00
PartialVolume
f66d838b23 Fix formatting in gui.c 2024-03-21 22:07:52 +00:00
PartialVolume
4fad31ec50 Fix a couple of formatting issues in prng.c 2024-03-21 22:03:24 +00:00
PartialVolume
0e03653ab5 Merge branch 'master' into xoroshiro256 2024-03-21 21:28:06 +00:00
Fabian Druschke
4e29f6c514 Renamed N and M to MT_STATE_SIZE and MT_MIDDLE_WORD due to const naming of mt19937ar-cok.h, causing conflicts with SHA-512 HMAC's libssl. 2024-03-21 17:28:57 -03:00
PartialVolume
d40c28bfc5 Merge pull request #556 from Knogle/fibonacci
Implemented Lagged Fibonacci generator PRNG providing high-speed, medium-quality numbers.
2024-03-21 18:49:16 +00:00
Fabian Druschke
0d0150393c Fixed stray / inside of options.c 2024-03-21 10:01:17 -03:00
Fabian Druschke
238656a5b4 Fixed leftovers from XORoshiro-256, fixed missing PRNG option in options.c 2024-03-21 05:01:10 -03:00
Fabian Druschke
a2d998d7c3 Fixed formatting 2024-03-20 17:48:55 -03:00
Fabian Druschke
a89dc8b9e9 Implemented Substract-and-Carry, now offering high-quality output. 2024-03-20 17:45:14 -03:00
Fabian Druschke
87376a0bbb Removed leftover references to AES-CTR, not belonging here. 2024-03-20 17:39:32 -03:00
Fabian Druschke
201eb565f9 Implemented Lagged Fibonacci generator PRNG providing high-speed, medium-security numbers. 2024-03-20 17:28:57 -03:00
Fabian Druschke
50bcf81ea6 Fixed src/temperature.c formatting 2024-03-19 08:25:09 -03:00
Fabian Druschke
5e532c9367 Rebased branch, fixed conflicts. Now Xoroshiro-256 in standalone branch 2024-03-19 08:24:38 -03:00
PartialVolume
cb595e139c Update README.md 2024-02-20 21:19:54 +00:00
PartialVolume
08f68f14d9 Merge pull request #549 from PartialVolume/Bump_version_to_0.36
Bump version to 0.36
2024-02-20 20:53:14 +00:00
PartialVolume
f17845c54b Updated CHANGELOG.md 2024-02-20 20:43:54 +00:00
PartialVolume
230e7f524a Bump to v0.36 2024-02-20 19:52:25 +00:00
PartialVolume
de077211e6 Merge pull request #548 from PartialVolume/Fix_some_strcpy_warnings_for_Debian
Fix some strcpy compiler warnings
2024-02-17 17:23:30 +00:00
PartialVolume
07a7c0ab0c Fix some strcpy compiler warnings
Replace three strcpy commands with strncpy,
bump minor version ready for more testing.
2024-02-17 17:00:37 +00:00
PartialVolume
2fae6ea5f5 Merge pull request #546 from PartialVolume/Determine_block_sizes_before_hidden_sector_detection
Populates device block size before hidden sector
2024-02-15 23:21:50 +00:00
PartialVolume
d6f7238cb3 Populates device block size before hidden sector
Now populates the block size (physical) before
the hidden sector determination function runs.

The naming of block/sector can be very confusing in
nwipe. So I have created a device_phy_sector_size
in the drive context, so we have

->device_sector_size // logical sector size
->device_phys_sector_size // physical sector size
->device_block_size // Usually the same as logical
size but could be increased by nwipe to encompass
multiple logical sectors, i.e a block of sectors
2024-02-15 23:11:09 +00:00
PartialVolume
c007d0f2ab Update version.c
Bump minor version from 0.35.6 to 0.35.7
2024-02-15 11:51:45 +00:00
PartialVolume
161054269c Merge pull request #543 from PartialVolume/Fix_incorrect_HS_status_for_4096_sectors_as_reported_by_libata
Fix hidden sector detection for logical 4096 size
2024-02-03 22:34:47 +00:00
PartialVolume
dd7ffab816 Fix hidden sector detection for logical 4096 size
This fixes an issue where nwipe detects a discrepancy
between the number of sectors reported by hdparm and
nwipe's own HPA/DCO functions that were reporting the
same values, using number of sectors based on 512 byte
sectors but disagreed with the number of sectors
generated from libata which was reporting the number of
sectors based on 4096 byte sectors.

This has been fixed by always calculating the number
of sectors returned by libata using 512 bytes per sector
so a direct comparison can be made to data from hdparm
& nwipe's HPA/DCO functions.
2024-02-03 20:20:39 +00:00
PartialVolume
9edebde20d Merge pull request #538 from PartialVolume/Make_footer_text_more_informative_at_end_of_all_wipes
Make completion footer more informative
2023-12-20 21:10:34 +00:00
PartialVolume
807eed0ffc Make completion footer more informative
These changes solve three issues. The first
issue was that it wasn't obvious that the
PDFs are only created once you press return
to exit after all the wipes have finished. It
is now explicitly stated in the footer message if
PDFs are enabled.

It also now specifies the logfile name on the
footer if the user has specified a log file as a
command line option. If no logfile is specified
then STDOUT is displayed.

If the user specified --PDFreportpath=noPDF on the
command line, prior to this commit it had no affect.
This is now fixed so that it disables PDF's irrespective
of what is in nwipe.conf. i.e command line options
override the entries in nwipe.conf

If the user has specified a --PDFreportpath=noPDF=/some/path
then PDF's are enabled irrespective of the value in nwipe.conf
2023-12-20 20:53:43 +00:00
PartialVolume
78f3a26795 Merge pull request #536 from PartialVolume/Bump_minor_version
Bump version from 0.35.3 to 0.35.4
2023-12-16 19:14:47 +00:00
PartialVolume
dbe7103fe9 Bump version from 0.35.3 to 0.35.4 2023-12-16 19:12:23 +00:00
PartialVolume
eef25e829e Merge pull request #535 from PartialVolume/Fix_incorrect_footer_on_return_to_preview
Fix incorrect footer on return to preview
2023-12-16 18:57:59 +00:00
PartialVolume
43bfb3a08e Fix incorrect footer on return to preview
This fixes incorrect footer text being displayed when
Enable customer/company preview is enabled and the user
select a field to be edited, completes the editing and
returns to the preview to select A for accept. Only
problem was A=Accept wasn't listed on the footer.
2023-12-16 18:50:33 +00:00
PartialVolume
fd6cca7010 Merge pull request #534 from PartialVolume/Fix_spacing_between_temperature_and_model
Place a space between temperature and model
2023-11-29 22:23:44 +00:00
PartialVolume
1220eca2ef Place a space between temperature and model
eg [36C] ST3500... and not [36C]ST3500..
2023-11-29 22:21:01 +00:00
PartialVolume
32321f49fa Merge pull request #533 from PartialVolume/Fix_config_key_shortcuts_help_text
Fix the config help messages.

Some of the config help messages that show the purpose of the keys were inconsistent or not updating correctly when going back to the previous menu. Now fixed.
2023-11-29 19:51:02 +00:00
PartialVolume
cca93f845d Fix the config help messages
Some of the help messages that show the
purpose of the keys were inconsistent or
not updated when going back. Now fixed.
2023-11-29 19:40:47 +00:00
PartialVolume
789aa134a0 Merge pull request #532 from PartialVolume/Fix_PDF_page_titles
Make smart page titles consistent with page 1

Should now read
Page 1 - Erasure Status
Page 2 - Smart Data
Page 3 - Smart Data

and not as previously
Page 1 - Erasure Status
Smart Data - Page 2
Smart Data - Page 3
2023-11-28 21:25:52 +00:00
PartialVolume
c24e248055 Make smart page titles consistent with page 1
Should now read
Page 1 - Erasure Status
Page 2 - Smart Data
Page 3 - Smart Data

and not as previously
Page 1 - Erasure Status
Smart Data - Page 2
Smart Data - Page 3
2023-11-28 21:21:48 +00:00
PartialVolume
3f78d76bac Merge pull request #531 from PartialVolume/Fix_no_auto_exit_in_non_gui_mode
Fix nwipe not auto exiting on completion in non gui mode.
2023-11-28 00:52:54 +00:00
PartialVolume
626ca3826c Fix nwipe not auto exiting on completion in non gui mode. 2023-11-27 23:39:50 +00:00
PartialVolume
f61b593093 Merge pull request #529 from PartialVolume/Fix_autopoweroff_and_nowait_when_screen_blank
Fix autopoweroff and nowait when screen blank
2023-11-24 01:14:31 +00:00
PartialVolume
7f39d81548 Fix autopoweroff and nowait when screen blank
If the user had blanked the screen, the autopoweroff
and nowait options did not work. Instead they paused
nwipe on completion of the wipe/s waiting for the b
key to be pressed which reactivated compute_stats()
function who's output indicates whether any wipes were
still active.

This was fixed so that compute_stats() is always
active while wipes are in progress, so that the
nwipe_gui_status() function will exit when all wipe
threads have completed even if the screen has been
blanked.
2023-11-24 01:06:29 +00:00
PartialVolume
d0a53f57be Merge pull request #527 from ggruber/SerialGarbage
fix: again garbage after serial number
2023-11-20 00:15:03 +00:00
Gerold Gruber
811c36b65a again garbage after serial number 2023-11-20 00:14:05 +01:00
PartialVolume
2ff23eb02c Update version.c
Bump minor version from 0.35 to 0.35.1
2023-11-17 12:04:48 +00:00
PartialVolume
7a4709da55 Merge pull request #526 from PartialVolume/Identify_mmcblk_devices
Added mmcblk device type MMC

Changed log message from "USB bridge, no pass-through support" to "Smart data unavailable" as no smart data could be caused by a non USB device such as mmcblk as well as USB devices with no ATA pass through and other devices that smartctl does not detect.
2023-11-16 20:00:13 +00:00
PartialVolume
9ee5193673 Added mmcblk device type MMC
Added the abbreviation MMC for mmcblk devices such as SD and
microSD cards and some low budget laptops.

Changed log message from "USB bridge, no pass-through support"
to "Smart data unavailable" as no smart data could be caused by
a non USB device such as mmcblk as well as USB devices with no ATA
pass through and other devices that smartctl does not detect.
2023-11-16 19:35:07 +00:00
26 changed files with 1081 additions and 431 deletions

View File

@@ -1,6 +1,32 @@
RELEASE NOTES
=============
v0.37
-----------------------
includes the following changes:
- Added the XORoshiro-256 pseudo random number generator (PRNG). Thanks to Fabian Druschke @knogle #555
- Added the Lagged Fibonacci PRNG generator. Thanks again to Fabian Druschke @knogle #556
- Added missing help for HMG IS5 enhanced. Thanks to @AndCycle #569
- Changed the default method from "DOD Short" to "prng stream", using the XORoshiro-256 prng
- Fixed an issue in configure.ac which was producing an error while running `./configure`, mentioning libconfig, however the presence of libconfig had already been checked for, earlier in configure.ac. Although this error did not cause `./configure` to abort prematurely and therefore make would build the source correctly, it did cause a issue for inclusion into Debian Sid. Thanks to @Polynomial-C #574
- Minor change to nwipe's man page filename, nwipe.1 to nwipe.8 to fix a Debian warning. #577
v0.36
-----------------------
- Added the abbreviation MMC for mmcblk devices such as SD and microSD cards and some low budget laptops. #526
- Fixed some serial numbers that were displaying garbage. #527
- Fixed auto power off and nowait when the screen has been blanked by the user. #529
- Fixed nwipe not auto exiting on completion when in non gui mode. #531
- Fixed smart page titles so they have a consistent format with page 1 in the PDF report. #532
- Fixed some of the config help messages that displayed incorrect information. #533
- Inserted a space between temperature and model. #534
- Fixed incorrect footer on return to organisation/customer preview screen. #535
- Made footer completion message more informative. #538
- Fixed hidden sector detection for devices with logical/physical size of 4096/4096. #543 #546
- Fixed some strcpy compiler warnings. #548
v0.35
-----------------------
- Nwipe will now optionally create a multi-page PDF certificate that shows details of a specific discs erasure. The first page forms the certificate of erasure and subsequent pages show the drives smart data. Two related options have been added to nwipe's command line options -P, --PDFreportpath=PATH Path to write PDF reports to. Default is "." If set to "noPDF" no PDF reports are written. From the drive selection screen you can now press 'c' for config. This takes you to the configuration screen where you can select various PDF certificate related options such as enabling PDF, entering customer or company data for entry onto the certificate and enabling a preview of customer/company info prior to the drive selection screen starting.

View File

@@ -9,14 +9,6 @@ nwipe is a program that will securely erase the entire contents of disks. It can
> **Warning**
> For some of nwipes features such as smart data in the PDF certificate, HPA/DCO detection and other uses, nwipe utilises smartmontools and hdparm. Therefore both hdparm & smartmontools are a mandatory requirement if you want all of nwipes features to be fully available. If you do not install smartmontools and hdparm, nwipe will provide a warning in the log that these programs cannot be found but will still run but many important features may not work as they should do.
# New Features in 0.35
- Nwipe now supports HPA/DCO (hidden disc area) detection. The status of a discs HPA/DCO is shown on nwipes's drive selection screen. This allows you to identify a drive that is reporting a smaller size than it actually is. To wipe the hidden sectors the HPA/DCO must be reset to the true size of the disc. Currently nwipe cannot reset the HPA/DCO (scheduled for 0.36). To reset the HPA/DCO you would need to manually perform a reset using the command line tool hdparm.
- Nwipe now optionally generates a multi page PDF certificate for each drive erased. Page one of the PDF is a erasure certificate that shows the erasure details such as drive make, model, serial number, bytes erased, HPA/DCO status, organisation performing the erase, customer details, technician name, status of erasure, errors detected.
- Nwipe now has a configuration file, /etc/nwipe/nwipe.conf. This is currently used to store PDF parameters but will be enhanced over the next versions to include default wipe parameters amongst other additions.
- There is a new configuration screen in nwipe. It can be accessed from the drive selection screen by typing 'c'. Curerntly the configuration screen allows changes to be made to the PDF certificate however later versions will expand this configuration screen.
- Nwipe now provides better support for temperature retrieval specifically on SAS hardware, so that both SATA and SAS drives should now all show temperatures both at drive selection and during the erasure.
- Nwipes temperature retrieval code has been placed in it's own thread. This was done because it was found that any delays in obtaining the temperature resulted in a momentary freeze in the GUI wipe screen updating it's stats. This wasn't noticable if you were erasing a small number of drives but become apparent when wiping ten or twenty drives simultaneously.
![Example wipe](/images/example_wipe.gif)
<i>The video above shows six drives being simultaneously erased. It skips to the completion of all six wipes and shows five drives that were successfully erased and one drive that failed due to an I/O error. The drive that failed would then normally be physically destroyed. The five drives that were successfully wiped with zero errors or failures can then be redeployed.</i>
@@ -38,10 +30,15 @@ The user can select from a variety of recognised secure erase methods which incl
* Verify Ones - This method only reads the device and checks that it is filled with ones (0xFF).
* HMG IS5 enhanced - Secure Sanitisation of Protectively Marked Information or Sensitive Information
nwipe also includes the following pseudo random number generators:
nwipe also includes the following pseudo random number generators (prng):
* Mersenne Twister
* ISAAC
In addition to the above, the following prngs will be available in v0.37
* XORoshiro-256
* Lagged Fibonacci
* AES-CTR (openssl)
These can be used to overwrite a drive with a stream of randomly generated characters.
nwipe can be found in many [Linux distro repositories](#which-linux-distro-uses-the-latest-nwipe).

View File

@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([nwipe],[0.35],[git@brumit.nl])
AC_INIT([nwipe],[0.37],[git@brumit.nl])
AM_INIT_AUTOMAKE(foreign subdir-objects)
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile])
AC_OUTPUT
@@ -69,7 +69,7 @@ PKG_CHECK_MODULES(
AC_CHECK_LIB([intl], [libintl_dgettext]) # needed to statically link libparted, but not given in its pkgconfig file
AC_CHECK_LIB([uuid], [uuid_generate]) # needed to statically link libparted, but not given in its pkgconfig file
PKG_CHECK_MODULES([PARTED], [libparted], [libconfig])
PKG_CHECK_MODULES([PARTED], [libparted])
AC_CHECK_LIB([pthread], [main], ,[AC_MSG_ERROR([pthread development library not found])])
# Checks for header files.

View File

@@ -1 +1 @@
dist_man_MANS = nwipe.1
dist_man_MANS = nwipe.8

View File

@@ -1,4 +1,4 @@
.TH NWIPE "24" "October 2023" "nwipe version 0.35" "User Commands"
.TH NWIPE "8" "May 2024" "nwipe version 0.37" "User Commands"
.SH NAME
nwipe \- securely erase disks
.SH SYNOPSIS
@@ -131,6 +131,7 @@ Number of times to wipe the device using the selected method (default: 1)
Up to ten comma separated devices to be excluded, examples:
--exclude=/dev/sdc
--exclude=/dev/sdc,/dev/sdd
--exclude=/dev/sdc,/dev/sdd,/dev/mapper/cryptswap1
.SH BUGS
Please see the GitHub site for the latest list
(https://github.com/martijnvanbrummelen/nwipe/issues)

View File

@@ -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 alfg/add_lagg_fibonacci_prng.h alfg/add_lagg_fibonacci_prng.c 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)

View File

@@ -0,0 +1,79 @@
/*
* Additive Lagged Fibonacci Generator (ALFG) Implementation
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This is an implementation of the Additive Lagged Fibonacci Generator (ALFG),
* a pseudorandom number generator known for its simplicity and good statistical properties
* for a wide range of applications. ALFGs are particularly noted for their long periods
* and efficiency in generating sequences of random numbers. However, like many other PRNGs,
* 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 is designed for non-cryptographic applications and should not be
* used where cryptographic security is required.
*/
#include "add_lagg_fibonacci_prng.h"
#include <stdint.h>
#include <string.h>
#define STATE_SIZE 64 // Size of the state array, sufficient for a high period
#define LAG_BIG 55 // Large lag, e.g., 55
#define LAG_SMALL 24 // Small lag, e.g., 24
#define MODULUS ( 1ULL << 48 ) // Modulus for the operations, here 2^48 for simple handling
void add_lagg_fibonacci_init( add_lagg_fibonacci_state_t* state, uint64_t init_key[], unsigned long key_length )
{
// Simple initialization: Fill the state with the key values and then with a linear combination of them
for( unsigned long i = 0; i < STATE_SIZE; i++ )
{
if( i < key_length )
{
state->s[i] = init_key[i];
}
else
{
// Simple method to generate further state values. Should be improved for serious applications.
state->s[i] = ( 6364136223846793005ULL * state->s[i - 1] + 1 ) % MODULUS;
}
}
state->index = 0; // Initialize the index for the first generation
}
void add_lagg_fibonacci_genrand_uint256_to_buf( add_lagg_fibonacci_state_t* state, unsigned char* bufpos )
{
uint64_t* buf_as_uint64 = (uint64_t*) bufpos; // Interprets bufpos as a uint64_t array for direct assignment
int64_t result; // Use signed integer to handle potential negative results from subtraction
for (int i = 0; i < 4; i++) {
// Subtract the two previous numbers in the sequence
result = (int64_t)state->s[(state->index + LAG_BIG) % STATE_SIZE] - (int64_t)state->s[(state->index + LAG_SMALL) % STATE_SIZE];
// Handle borrow if result is negative
if (result < 0) {
result += MODULUS;
// Optionally set a borrow flag or adjust the next operation based on borrow logic
}
// Store the result (after adjustment) back into the state, ensuring it's positive and within range
state->s[state->index] = (uint64_t)result;
// Write the result into buf_as_uint64
buf_as_uint64[i] = state->s[state->index];
// Update the index for the next round
state->index = (state->index + 1) % STATE_SIZE;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Additive Lagged Fibonacci Generator (ALFG) Implementation definitions
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This is an implementation of the Additive Lagged Fibonacci Generator (ALFG),
* a pseudorandom number generator known for its simplicity and good statistical properties
* for a wide range of applications. ALFGs are particularly noted for their long periods
* and efficiency in generating sequences of random numbers. However, like many other PRNGs,
* 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 is designed for non-cryptographic applications and should not be
* used where cryptographic security is required.
*/
#ifndef ADD_LAGG_FIBONACCI_PRNG_H
#define ADD_LAGG_FIBONACCI_PRNG_H
#include <stdint.h>
// State definition for the Additive Lagged Fibonacci Generator
typedef struct
{
uint64_t s[64]; // State array
unsigned int index; // Current index in the state array
} add_lagg_fibonacci_state_t;
// Function prototypes
void add_lagg_fibonacci_init( add_lagg_fibonacci_state_t* state, uint64_t init_key[], unsigned long key_length );
void add_lagg_fibonacci_genrand_uint256_to_buf( add_lagg_fibonacci_state_t* state, unsigned char* bufpos );
#endif // ADD_LAGG_FIBONACCI_PRNG_H

View File

@@ -392,11 +392,12 @@ int nwipe_conf_update_setting( char* group_name_setting_name, char* setting_valu
int nwipe_conf_read_setting( char* group_name_setting_name, const char** setting_value )
{
/* You would call this function if you wanted to read a settings value in nwipe.conf, i.e
/* This function returns a setting value from nwipe's configuration file nwipe.conf
* when provided with a groupname.settingname string.
*
* Example:
* const char ** pReturnString;
* nwipe_conf_read_setting( "PDF_Certificate", "PDF_Enable", pReturnString );
*
*/
/* Separate group_name_setting_name i.e "PDF_Certificate.PDF_Enable" string
@@ -406,20 +407,20 @@ int nwipe_conf_read_setting( char* group_name_setting_name, const char** setting
int return_status;
int length = strlen( group_name_setting_name );
char* group_name = malloc( length );
char* setting_name = malloc( length );
char* group_name = calloc( length, sizeof( char ) );
char* setting_name = calloc( length, sizeof( char ) );
int idx = 0;
while( group_name_setting_name[idx] != 0 && group_name_setting_name[idx] != '.' )
{
if( group_name_setting_name[idx] == '.' )
{
break;
}
idx++;
}
// Copy the group name from the combined input string
memcpy( group_name, group_name_setting_name, idx );
group_name[idx] = '\0'; // Null-terminate group_name
// Copy the setting name from the combined input string
strcpy( setting_name, &group_name_setting_name[idx + 1] );
if( !( setting = config_lookup( &nwipe_cfg, group_name ) ) )

View File

@@ -38,7 +38,8 @@ typedef enum nwipe_device_t_ {
NWIPE_DEVICE_ATA,
NWIPE_DEVICE_NVME,
NWIPE_DEVICE_VIRT,
NWIPE_DEVICE_SAS
NWIPE_DEVICE_SAS,
NWIPE_DEVICE_MMC
} nwipe_device_t;
typedef enum nwipe_pass_t_ {
@@ -78,13 +79,17 @@ typedef struct nwipe_speedring_t_
// Arbitrary length, so far most paths don't exceed about 25 characters
#define MAX_HWMON_PATH_LENGTH 100
// 20 chracters for serial number plus null Byte
#define NWIPE_SERIALNUMBER_LENGTH 20
typedef struct nwipe_context_t_
{
/*
* Device fields
*/
int device_block_size; // The soft block size reported by the device.
int device_sector_size; // The hard sector size reported by the device.
int device_block_size; // The soft block size reported by the device, as logical
int device_sector_size; // The logical sector size reported by libparted
int device_phys_sector_size; // The physical sector size reported by libparted
int device_bus; // The device bus number.
int device_fd; // The file descriptor of the device file being wiped.
int device_host; // The host number.
@@ -97,7 +102,9 @@ typedef struct nwipe_context_t_
char device_name_without_path[100];
char gui_device_name[100];
unsigned long long device_size; // The device size in bytes.
u64 device_size_in_sectors; // The device size in sectors
u64 device_size_in_sectors; // The device size in number of logical sectors, this may be 512 or 4096 sectors
u64 device_size_in_512byte_sectors; // The device size in number of 512byte sectors, irrespective of logical sector
// size reported by libata
unsigned long long bytes_erased; // Irrespective of pass, this how much of the drive has been erased, CANNOT be
// greater than device_size.
char* device_size_text; // The device size in a more (human)readable format.
@@ -108,7 +115,8 @@ typedef struct nwipe_context_t_
nwipe_device_t device_type; // Indicates an IDE, SCSI, or Compaq SMART device in enumerated form (int)
char device_type_str[14]; // Indicates an IDE, SCSI, USB etc as per nwipe_device_t but in ascii
int device_is_ssd; // 0 = no SSD, 1 = is a SSD
char device_serial_no[21]; // Serial number(processed, 20 characters plus null termination) of the device.
char device_serial_no[NWIPE_SERIALNUMBER_LENGTH
+ 1]; // Serial number(processed, 20 characters plus null termination) of the device.
int device_target; // The device target.
u64 eta; // The estimated number of seconds until method completion.

View File

@@ -63,6 +63,8 @@ int create_pdf( nwipe_context_t* ptr )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern nwipe_prng_t nwipe_isaac64;
extern nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/* Used by libconfig functions to retrieve data from nwipe.conf defined in conf.c */
extern config_t nwipe_cfg;
@@ -466,7 +468,21 @@ int create_pdf( nwipe_context_t* ptr )
}
else
{
snprintf( prng_type, sizeof( prng_type ), "Unknown" );
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
snprintf( prng_type, sizeof( prng_type ), "Fibonacci" );
}
else
{
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
snprintf( prng_type, sizeof( prng_type ), "XORshiro256" );
}
else
{
snprintf( prng_type, sizeof( prng_type ), "Unknown" );
}
}
}
}
}
@@ -872,7 +888,7 @@ int nwipe_get_smart_data( nwipe_context_t* c )
page = pdf_append_page( pdf );
/* Create the header and footer for page 2, the start of the smart data */
snprintf( page_title, sizeof( page_title ), "Smart Data - Page %i", page_number );
snprintf( page_title, sizeof( page_title ), "Page %i - Smart Data", page_number );
create_header_and_footer( c, page_title );
/* Read the output a line at a time - output it. */
@@ -930,7 +946,7 @@ int nwipe_get_smart_data( nwipe_context_t* c )
y = 630;
/* create the header and footer for the next page */
snprintf( page_title, sizeof( page_title ), "Smart Data - Page %i", page_number );
snprintf( page_title, sizeof( page_title ), "Page %i - Smart Data", page_number );
create_header_and_footer( c, page_title );
}
}

View File

@@ -131,7 +131,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
int fd;
int idx;
int r;
char tmp_serial[21];
char tmp_serial[NWIPE_SERIALNUMBER_LENGTH + 1];
nwipe_device_t bus;
int is_ssd;
int check_HPA; // a flag that indicates whether we check for a HPA on this device
@@ -229,8 +229,11 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
}
next_device->device_size = dev->length * dev->sector_size;
next_device->device_sector_size = dev->sector_size;
next_device->device_sector_size = dev->sector_size; // logical sector size
next_device->device_block_size = dev->sector_size; // set as logical but could be a multiple of logical sector size
next_device->device_phys_sector_size = dev->phys_sector_size; // physical sector size
next_device->device_size_in_sectors = next_device->device_size / next_device->device_sector_size;
next_device->device_size_in_512byte_sectors = next_device->device_size / 512;
Determine_C_B_nomenclature( next_device->device_size, next_device->device_size_txt, NWIPE_DEVICE_SIZE_TXT_LENGTH );
next_device->device_size_text = next_device->device_size_txt;
next_device->result = -2;
@@ -252,7 +255,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
ioctl( fd, HDIO_GET_IDENTITY, &next_device->identity );
close( fd );
for( idx = 0; idx < 20; idx++ )
for( idx = 0; idx < NWIPE_SERIALNUMBER_LENGTH; idx++ )
{
if( isascii( next_device->identity.serial_no[idx] ) && !iscntrl( next_device->identity.serial_no[idx] ) )
{
@@ -280,7 +283,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
/* If the serial number hasn't already been populated */
if( next_device->device_serial_no[0] == 0 )
{
strcpy( next_device->device_serial_no, tmp_serial );
strncpy( next_device->device_serial_no, tmp_serial, NWIPE_SERIALNUMBER_LENGTH );
}
}
@@ -289,13 +292,16 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
{
if( next_device->device_serial_no[0] == 0 )
{
strcpy( next_device->device_serial_no, "???????????????" );
strncpy( next_device->device_serial_no, "????????????????????", NWIPE_SERIALNUMBER_LENGTH + 1 );
}
else
{
strcpy( next_device->device_serial_no, "XXXXXXXXXXXXXXX" );
strncpy( next_device->device_serial_no, "XXXXXXXXXXXXXXXXXXXX", NWIPE_SERIALNUMBER_LENGTH + 1 );
}
}
/* strncpy would have copied the null terminator BUT just to be sure, just in case somebody changes the length
* of those strings we should explicitly terminate the string */
next_device->device_serial_no[NWIPE_SERIALNUMBER_LENGTH] = 0;
/* Initialise the variables that toggle the [size][temp c] with [HPA status]
* Not currently used, but may be used in the future or for other purposes
@@ -365,6 +371,10 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
strcpy( next_device->device_type_str, " SAS" );
check_HPA = 1;
break;
case NWIPE_DEVICE_MMC:
strcpy( next_device->device_type_str, " MMC" );
break;
}
if( next_device->device_is_ssd )
{
@@ -405,6 +415,12 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
next_device->device_size_text,
next_device->device_serial_no );
nwipe_log( NWIPE_LOG_INFO,
"%s, sector(logical)/block(physical) sizes %i/%i",
next_device->device_name,
dev->sector_size,
dev->phys_sector_size );
/******************************
* Check for hidden sector_size
*/
@@ -638,6 +654,13 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, i
{
*bus = NWIPE_DEVICE_VIRT;
}
else
{
if( strstr( result, "/mmcblk" ) != 0 )
{
*bus = NWIPE_DEVICE_MMC;
}
}
}
}
}
@@ -783,7 +806,8 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, i
/* strip any leading or trailing spaces and left justify, +15 is the length of "Serial Number:" */
trim( &result[15] );
strncpy( serialnumber, &result[15], 20 );
strncpy( serialnumber, &result[15], NWIPE_SERIALNUMBER_LENGTH );
serialnumber[NWIPE_SERIALNUMBER_LENGTH] = 0;
}
if( *bus == 0 )
@@ -859,9 +883,9 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, i
if( exit_status == 1 )
{
nwipe_log( NWIPE_LOG_WARNING, "%s USB bridge, no pass-through support", device );
nwipe_log( NWIPE_LOG_WARNING, "Smartctl is unable to provide smart data for %s", device );
if( *bus == NWIPE_DEVICE_USB )
if( *bus == NWIPE_DEVICE_USB || *bus == NWIPE_DEVICE_MMC )
{
strcpy( serialnumber, "(S/N: unknown)" );
set_return_value = 5;

674
src/gui.c
View File

@@ -160,15 +160,14 @@ const char* main_window_footer_warning_no_drive_selected =
/* Oddly enough, placing extra quotes around the footer strings fixes corruption to the right
* of the footer message when the terminal is resized, a quirk in ncurses? - DO NOT REMOVE THE \" */
const char* selection_footer = "J=Down K=Up Space=Select Backspace=Cancel Ctrl+C=Quit";
const char* selection_footer_config = "J=Down K=Up Return=Select ESC|Backspace=back Ctrl+C=Quit";
const char* selection_footer_preview_prior_to_drive_selection =
"A=Accept & display drives J=Down K=Up Space=Select Backspace=Cancel Ctrl+C=Quit";
const char* selection_footer_add_customer = "S=Save J=Down K=Up Space=Select Backspace=Cancel Ctrl+C=Quit";
const char* selection_footer_add_customer_yes_no = "Save Customer Details Y/N";
const char* end_wipe_footer = "B=[Toggle between dark\\blank\\blue screen] Ctrl+C=Quit";
const char* rounds_footer = "Left=Erase Esc=Cancel Ctrl+C=Quit";
const char* selection_footer_text_entry = "Esc=Cancel Ctrl+C=Quit";
const char* wipes_finished_footer = "Wipe finished - press enter to exit. Logged to STDOUT";
const char* selection_footer_text_entry = "Esc=Cancel Return=Submit Ctrl+C=Quit";
/* The number of lines available in the terminal */
int stdscr_lines;
@@ -1600,10 +1599,14 @@ 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 nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern int terminate_signal;
/* The number of implemented PRNGs. */
const int count = 3;
const int count = 5;
/* The first tabstop. */
const int tab1 = 2;
@@ -1637,7 +1640,14 @@ void nwipe_gui_prng( void )
{
focus = 2;
}
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
focus = 3;
}
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
focus = 4;
}
do
{
/* Clear the main window. */
@@ -1652,6 +1662,8 @@ 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_add_lagg_fibonacci_prng.label );
mvwprintw( main_window, yy++, tab1, " %s", nwipe_xoroshiro256_prng.label );
yy++;
/* Print the cursor. */
@@ -1735,7 +1747,100 @@ 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,
"ALFG (Additive Lagged Fibonacci Generator), is a class of PRNGs utilizing" );
mvwprintw( main_window,
yy++,
tab1,
"the Fibonacci sequence with additive operations between lagged values. While" );
mvwprintw( main_window,
yy++,
tab1,
"they offer a good balance between speed and randomness, it's important to note" );
mvwprintw( main_window,
yy++,
tab1,
"that they provide lower levels of security, making them less suitable for" );
mvwprintw( main_window,
yy++,
tab1,
"cryptographic applications. Their periodicity depends on the choice of lags" );
mvwprintw( main_window,
yy++,
tab1,
"and arithmetic operations, potentially achieving large values, often 2^N or" );
mvwprintw( main_window,
yy++,
tab1,
"higher, where N is the bit length of the states. " );
mvwprintw( main_window,
yy++,
tab1,
" " );
mvwprintw( main_window,
yy++,
tab1,
"Efficient on CPUs of any bit width, particularly suited for non-cryptographic" );
mvwprintw( main_window,
yy++,
tab1,
"applications requiring long sequences with a good speed-randomness trade-off. " );
break;
case 4:
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 );
@@ -1795,6 +1900,14 @@ void nwipe_gui_prng( void )
{
nwipe_options.prng = &nwipe_isaac64;
}
if( focus == 3 )
{
nwipe_options.prng = &nwipe_add_lagg_fibonacci_prng;
}
if( focus == 4 )
{
nwipe_options.prng = &nwipe_xoroshiro256_prng;
}
return;
case KEY_BACKSPACE:
@@ -2496,17 +2609,17 @@ void nwipe_gui_config( void )
/* Input buffer. */
int keystroke;
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer );
wrefresh( footer_window );
do
{
/* Clear the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer_config );
wrefresh( footer_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_config );
/* Initialize the working row. */
yy = 2;
@@ -2530,19 +2643,17 @@ void nwipe_gui_config( void )
{
case 0:
mvwprintw( main_window, 2, tab2, "PDF Report - Enable/Disable" );
mvwprintw( main_window, 4, tab2, "Enable or Disable creation of the PDF " );
mvwprintw( main_window, 5, tab2, "report/certificate " );
if( nwipe_options.PDF_enable )
{
mvwprintw( main_window, 7, tab2, "Create PDF Report = ENABLED" );
mvwprintw( main_window, 2, tab2, "PDF Report = ENABLED" );
}
else
{
mvwprintw( main_window, 7, tab2, "Create PDF Report = DISABLED" );
mvwprintw( main_window, 2, tab2, "PDF Report = DISABLED" );
}
mvwprintw( main_window, 4, tab2, "Enable or Disable creation of the PDF " );
mvwprintw( main_window, 5, tab2, "report/certificate " );
break;
case 1:
@@ -2612,8 +2723,14 @@ void nwipe_gui_config( void )
case 6:
mvwprintw( main_window, 2, tab2, "PDF Report - Enable Preview at Start " );
if( nwipe_options.PDF_preview_details )
{
mvwprintw( main_window, 2, tab2, "Preview Org. & Customer at start = ENABLED" );
}
else
{
mvwprintw( main_window, 2, tab2, "Preview Org. & Customer at start = DISABLED" );
}
mvwprintw( main_window, 4, tab2, "A preview prior to the drive selection" );
mvwprintw( main_window, 5, tab2, "of the organisation that is performing" );
mvwprintw( main_window, 6, tab2, "the wipe, the customer details and the" );
@@ -2621,15 +2738,6 @@ void nwipe_gui_config( void )
mvwprintw( main_window, 8, tab2, "confirm that the information is " );
mvwprintw( main_window, 9, tab2, "correct on the pdf report prior to " );
mvwprintw( main_window, 10, tab2, "drive selection and starting the erase" );
if( nwipe_options.PDF_preview_details )
{
mvwprintw( main_window, 12, tab2, "Preview at start = ENABLED" );
}
else
{
mvwprintw( main_window, 12, tab2, "Preview at start = DISABLED" );
}
break;
case 8:
@@ -2774,7 +2882,7 @@ void nwipe_gui_config( void )
keystroke = -1;
}
} while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && terminate_signal != 1 );
} while( keystroke != KEY_ENTER && /* keystroke != ' ' && */ keystroke != 10 && terminate_signal != 1 );
} /* end of nwipe_config() */
@@ -2810,11 +2918,6 @@ void nwipe_gui_edit_organisation( void )
const char *business_name, *business_address, *contact_name, *contact_phone, *op_tech_name;
extern config_t nwipe_cfg;
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer );
wrefresh( footer_window );
do
{
do
@@ -2822,7 +2925,12 @@ void nwipe_gui_edit_organisation( void )
/* Clear the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer_config );
wrefresh( footer_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_config );
/* Initialize the working row. */
yy = 2;
@@ -2941,7 +3049,7 @@ void nwipe_gui_edit_organisation( void )
} /* switch */
} while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && terminate_signal != 1 );
} while( keystroke != KEY_ENTER && keystroke != 10 && terminate_signal != 1 );
if( keystroke == KEY_ENTER || keystroke == 10 || keystroke == ' ' )
{
@@ -2974,7 +3082,7 @@ void nwipe_gui_edit_organisation( void )
}
}
} while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && terminate_signal != 1 );
} while( keystroke != KEY_ENTER && keystroke != 10 && terminate_signal != 1 );
} /* end of nwipe_gui_edit_organisation( void ) */
@@ -3013,7 +3121,7 @@ void nwipe_gui_organisation_business_name( const char* business_name )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, rounds_footer );
nwipe_gui_title( footer_window, selection_footer_text_entry );
wrefresh( footer_window );
/* Copy the current business name to the buffer */
@@ -3027,7 +3135,7 @@ void nwipe_gui_organisation_business_name( const char* business_name )
/* Erase the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry );
/* Add a border. */
box( main_window, 0, 0 );
@@ -3153,7 +3261,7 @@ void nwipe_gui_organisation_business_address( const char* business_address )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, rounds_footer );
nwipe_gui_title( footer_window, selection_footer_text_entry );
wrefresh( footer_window );
/* Copy the current business address to the buffer */
@@ -3167,7 +3275,7 @@ void nwipe_gui_organisation_business_address( const char* business_address )
/* Erase the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry );
/* Add a border. */
box( main_window, 0, 0 );
@@ -3294,7 +3402,7 @@ void nwipe_gui_organisation_contact_name( const char* contact_name )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, rounds_footer );
nwipe_gui_title( footer_window, selection_footer_text_entry );
wrefresh( footer_window );
/* Copy the current business address to the buffer */
@@ -3308,7 +3416,7 @@ void nwipe_gui_organisation_contact_name( const char* contact_name )
/* Erase the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry );
/* Add a border. */
box( main_window, 0, 0 );
@@ -3434,7 +3542,7 @@ void nwipe_gui_organisation_contact_phone( const char* contact_phone )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, rounds_footer );
nwipe_gui_title( footer_window, selection_footer_text_entry );
wrefresh( footer_window );
/* Copy the current business address to the buffer */
@@ -3448,7 +3556,7 @@ void nwipe_gui_organisation_contact_phone( const char* contact_phone )
/* Erase the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry );
/* Add a border. */
box( main_window, 0, 0 );
@@ -3574,7 +3682,7 @@ void nwipe_gui_organisation_op_tech_name( const char* op_tech_name )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, rounds_footer );
nwipe_gui_title( footer_window, selection_footer_text_entry );
wrefresh( footer_window );
/* Copy the current op_tech_name to the buffer */
@@ -3588,7 +3696,7 @@ void nwipe_gui_organisation_op_tech_name( const char* op_tech_name )
/* Erase the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry );
/* Add a border. */
box( main_window, 0, 0 );
@@ -4094,7 +4202,7 @@ void nwipe_gui_add_customer( void )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer_add_customer );
nwipe_gui_title( footer_window, selection_footer_config );
wrefresh( footer_window );
do
@@ -4118,10 +4226,10 @@ void nwipe_gui_add_customer( void )
{
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer_add_customer );
nwipe_gui_title( footer_window, selection_footer_config );
wrefresh( footer_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_add_customer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_config );
}
/* Initialize the working row. */
yy = 2;
@@ -4221,10 +4329,10 @@ void nwipe_gui_add_customer( void )
}
}
} while( save != YES && keystroke != 's' && keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10
} while( save != YES && keystroke != 's' && keystroke != KEY_ENTER && keystroke != 10
&& terminate_signal != 1 );
if( keystroke == KEY_ENTER || keystroke == 10 || keystroke == ' ' )
if( keystroke == KEY_ENTER || keystroke == 10 )
{
switch( focus )
{
@@ -4730,18 +4838,6 @@ void nwipe_gui_preview_org_customer( int mode )
const char *customer_name, *customer_address, *customer_contact_name, *customer_contact_phone;
extern config_t nwipe_cfg;
/* Update the footer window. */
werase( footer_window );
if( mode == SHOWING_IN_CONFIG_MENUS )
{
nwipe_gui_title( footer_window, selection_footer );
}
else
{
nwipe_gui_title( footer_window, selection_footer_preview_prior_to_drive_selection );
}
wrefresh( footer_window );
do
{
do
@@ -4749,14 +4845,19 @@ void nwipe_gui_preview_org_customer( int mode )
/* Clear the main window. */
werase( main_window );
/* Update the footer window. */
werase( footer_window );
if( mode == SHOWING_IN_CONFIG_MENUS )
{
nwipe_gui_title( footer_window, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
}
else
{
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_preview_prior_to_drive_selection );
nwipe_gui_title( footer_window, selection_footer_preview_prior_to_drive_selection );
}
wrefresh( footer_window );
/* Determine size of window */
getmaxyx( main_window, wlines, wcols );
@@ -5070,7 +5171,7 @@ void nwipe_gui_set_date_time( void )
/* Update the footer window. */
werase( footer_window );
nwipe_gui_title( footer_window, selection_footer );
nwipe_gui_title( footer_window, selection_footer_config );
wrefresh( footer_window );
do
@@ -5080,7 +5181,7 @@ void nwipe_gui_set_date_time( void )
/* Clear the main window. */
werase( main_window );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_config );
/* Determine size of window */
getmaxyx( main_window, wlines, wcols );
@@ -6078,6 +6179,53 @@ void* nwipe_gui_status( void* ptr )
/* Spinner character */
char spinner_string[2];
/* Create the finish message, this changes based on whether PDF creation is enabled
* and whether a logfile has been specified
*/
char finish_message[NWIPE_GUI_FOOTER_W + 132];
if( nwipe_options.logfile[0] == 0 && nwipe_options.PDF_enable != 0 )
{
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to create pdfs & exit. Logged to STDOUT" );
}
else
{
if( nwipe_options.logfile[0] != 0 && nwipe_options.PDF_enable != 0 )
{
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to create pdfs & exit. Logged to %s",
nwipe_options.logfile );
}
else
{
if( nwipe_options.logfile[0] != 0 && nwipe_options.PDF_enable == 0 )
{
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to exit (pdfs disabled in config). Logged to %s",
nwipe_options.logfile );
}
else
{
if( nwipe_options.logfile[0] == 0 && nwipe_options.PDF_enable == 0 )
{
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to exit (pdfs disabled in config). Logged to STDOUT" );
}
else
{
/* This is a catch all something unexpected happens with the above logic */
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to exit. Logged to STDOUT" );
}
}
}
}
/* We count time from when this function is first called. */
static time_t nwipe_time_start = 0;
@@ -6235,7 +6383,7 @@ void* nwipe_gui_status( void* ptr )
else
{
/* and if the wipes have finished a different footer is required */
nwipe_gui_create_all_windows_on_terminal_resize( 0, wipes_finished_footer );
nwipe_gui_create_all_windows_on_terminal_resize( 0, finish_message );
}
}
@@ -6253,7 +6401,7 @@ void* nwipe_gui_status( void* ptr )
if( nwipe_active == 0 || terminate_signal == 1 )
{
nwipe_gui_title( footer_window, wipes_finished_footer );
nwipe_gui_title( footer_window, finish_message );
// Refresh the footer_window ;
wnoutrefresh( footer_window );
@@ -6395,250 +6543,248 @@ void* nwipe_gui_status( void* ptr )
}
/* Update data in statistics & main windows only if we're in 'gui' mode and only if a wipe has started */
if( nwipe_gui_blank == 0 && global_wipe_status == 1 )
if( global_wipe_status == 1 )
{
/* Always run compute_stats() as we need to whether any threads are still active */
if( terminate_signal != 1 )
{
nwipe_active = compute_stats( ptr ); // Returns number of active wipe threads
}
/* Print information for the user. */
for( i = offset; i < offset + slots && i < count; i++ )
/* Only print the stats if the user hasn't blanked the screen */
if( nwipe_gui_blank == 0 )
{
/* Print the device details. */
mvwprintw( main_window,
yy++,
2,
"%s %s [%s] ",
c[i]->device_name,
c[i]->device_type_str,
c[i]->device_size_text );
wprintw_temperature( c[i] );
wprintw( main_window, "%s/%s", c[i]->device_model, c[i]->device_serial_no );
/* Check whether the child process is still running the wipe. */
if( c[i]->wipe_status == 1 )
/* Print information for the user. */
for( i = offset; i < offset + slots && i < count; i++ )
{
/* Print percentage and pass information. */
/* Print the device details. */
mvwprintw( main_window,
yy++,
4,
"[%5.2f%%, round %i of %i, pass %i of %i] ",
c[i]->round_percent,
c[i]->round_working,
c[i]->round_count,
c[i]->pass_working,
c[i]->pass_count );
2,
"%s %s [%s] ",
c[i]->device_name,
c[i]->device_type_str,
c[i]->device_size_text );
wprintw_temperature( c[i] );
wprintw( main_window, " %s/%s", c[i]->device_model, c[i]->device_serial_no );
} /* child running */
else
{
if( c[i]->result == 0 )
/* Check whether the child process is still running the wipe. */
if( c[i]->wipe_status == 1 )
{
mvwprintw( main_window, yy++, 4, "[%05.2f%% complete, SUCCESS! ", c[i]->round_percent );
/* Print percentage and pass information. */
mvwprintw( main_window,
yy++,
4,
"[%5.2f%%, round %i of %i, pass %i of %i] ",
c[i]->round_percent,
c[i]->round_working,
c[i]->round_count,
c[i]->pass_working,
c[i]->pass_count );
} /* child running */
else
{
if( c[i]->result == 0 )
{
mvwprintw( main_window, yy++, 4, "[%05.2f%% complete, SUCCESS! ", c[i]->round_percent );
}
else if( c[i]->signal )
{
wattron( main_window, COLOR_PAIR( 9 ) );
mvwprintw( main_window, yy++, 4, "(>>> FAILURE! <<<, signal %i) ", c[i]->signal );
wattroff( main_window, COLOR_PAIR( 9 ) );
}
else
{
wattron( main_window, COLOR_PAIR( 9 ) );
mvwprintw( main_window, yy++, 4, "(>>> IOERROR! <<<, code %i) ", c[i]->result );
wattroff( main_window, COLOR_PAIR( 9 ) );
}
} /* child returned */
if( c[i]->verify_errors )
{
wprintw( main_window, "[verr:%llu] ", c[i]->verify_errors );
}
else if( c[i]->signal )
if( c[i]->pass_errors )
{
wattron( main_window, COLOR_PAIR( 9 ) );
mvwprintw( main_window, yy++, 4, "(>>> FAILURE! <<<, signal %i) ", c[i]->signal );
wattroff( main_window, COLOR_PAIR( 9 ) );
wprintw( main_window, "[perr:%llu] ", c[i]->pass_errors );
}
if( c[i]->wipe_status == 1 )
{
switch( c[i]->pass_type )
{
/* Each text field in square brackets should be the same number of characters
* to retain output in columns */
case NWIPE_PASS_FINAL_BLANK:
if( !c[i]->sync_status )
{
wprintw( main_window, "[ blanking] " );
}
break;
case NWIPE_PASS_FINAL_OPS2:
if( !c[i]->sync_status )
{
wprintw( main_window, "[OPS2final] " );
}
break;
case NWIPE_PASS_WRITE:
if( !c[i]->sync_status )
{
wprintw( main_window, "[ writing ] " );
}
break;
case NWIPE_PASS_VERIFY:
if( !c[i]->sync_status )
{
wprintw( main_window, "[verifying] " );
}
break;
case NWIPE_PASS_NONE:
break;
}
if( c[i]->sync_status )
{
wprintw( main_window, "[ syncing ] " );
}
}
/* Determine throughput nomenclature for this drive and output drives throughput to GUI */
Determine_C_B_nomenclature(
c[i]->throughput, nomenclature_result_str, NOMENCLATURE_RESULT_STR_SIZE );
wprintw( main_window, "[%s/s] ", nomenclature_result_str );
/* Insert whitespace. */
yy += 1;
/* Increment the next spinner character for this context if the thread is active */
if( c[i]->wipe_status == 1 )
{
spinner( c, i );
spinner_string[0] = c[i]->spinner_character[0];
}
else
{
wattron( main_window, COLOR_PAIR( 9 ) );
mvwprintw( main_window, yy++, 4, "(>>> IOERROR! <<<, code %i) ", c[i]->result );
wattroff( main_window, COLOR_PAIR( 9 ) );
}
} /* child returned */
if( c[i]->verify_errors )
{
wprintw( main_window, "[verr:%llu] ", c[i]->verify_errors );
}
if( c[i]->pass_errors )
{
wprintw( main_window, "[perr:%llu] ", c[i]->pass_errors );
}
if( c[i]->wipe_status == 1 )
{
switch( c[i]->pass_type )
{
/* Each text field in square brackets should be the same number of characters
* to retain output in columns */
case NWIPE_PASS_FINAL_BLANK:
if( !c[i]->sync_status )
{
wprintw( main_window, "[ blanking] " );
}
break;
case NWIPE_PASS_FINAL_OPS2:
if( !c[i]->sync_status )
{
wprintw( main_window, "[OPS2final] " );
}
break;
case NWIPE_PASS_WRITE:
if( !c[i]->sync_status )
{
wprintw( main_window, "[ writing ] " );
}
break;
case NWIPE_PASS_VERIFY:
if( !c[i]->sync_status )
{
wprintw( main_window, "[verifying] " );
}
break;
case NWIPE_PASS_NONE:
break;
}
if( c[i]->sync_status )
{
wprintw( main_window, "[ syncing ] " );
/* If the wipe thread is no longer active, replace the spinner with a space */
spinner_string[0] = ' ';
}
spinner_string[1] = 0;
wprintw( main_window, " %s ", spinner_string );
}
/* Determine throughput nomenclature for this drive and output drives throughput to GUI */
Determine_C_B_nomenclature( c[i]->throughput, nomenclature_result_str, NOMENCLATURE_RESULT_STR_SIZE );
wprintw( main_window, "[%s/s] ", nomenclature_result_str );
/* Insert whitespace. */
yy += 1;
/* Increment the next spinner character for this context if the thread is active */
if( c[i]->wipe_status == 1 )
if( offset > 0 )
{
spinner( c, i );
spinner_string[0] = c[i]->spinner_character[0];
mvwprintw( main_window, 1, wcols - 8, " More " );
waddch( main_window, ACS_UARROW );
}
else
if( count - offset > slots )
{
/* If the wipe thread is no longer active, replace the spinner with a space */
spinner_string[0] = ' ';
mvwprintw( main_window, wlines - 2, wcols - 8, " More " );
waddch( main_window, ACS_DARROW );
}
spinner_string[1] = 0;
wprintw( main_window, " %s ", spinner_string );
}
if( offset > 0 )
{
mvwprintw( main_window, 1, wcols - 8, " More " );
waddch( main_window, ACS_UARROW );
}
/* Box the main window. */
box( main_window, 0, 0 );
if( count - offset > slots )
{
mvwprintw( main_window, wlines - 2, wcols - 8, " More " );
waddch( main_window, ACS_DARROW );
}
/* Refresh the main window. */
wnoutrefresh( main_window );
/* Box the main window. */
box( main_window, 0, 0 );
/* Update the load average field, but only if we are still wiping */
if( nwipe_active && terminate_signal != 1 )
{
nwipe_gui_load();
}
/* Refresh the main window. */
wnoutrefresh( main_window );
nwipe_throughput = nwipe_misc_thread_data->throughput;
/* Update the load average field, but only if we are still wiping */
if( nwipe_active && terminate_signal != 1 )
{
nwipe_gui_load();
}
/* Determine the nomenclature for the combined throughput */
Determine_C_B_nomenclature( nwipe_throughput, nomenclature_result_str, NOMENCLATURE_RESULT_STR_SIZE );
nwipe_throughput = nwipe_misc_thread_data->throughput;
/* Print the combined throughput. */
mvwprintw( stats_window, NWIPE_GUI_STATS_THROUGHPUT_Y, NWIPE_GUI_STATS_THROUGHPUT_X, "Throughput:" );
/* Determine the nomenclature for the combined throughput */
Determine_C_B_nomenclature( nwipe_throughput, nomenclature_result_str, NOMENCLATURE_RESULT_STR_SIZE );
mvwprintw(
stats_window, NWIPE_GUI_STATS_THROUGHPUT_Y, NWIPE_GUI_STATS_TAB, "%s/s", nomenclature_result_str );
/* Print the combined throughput. */
mvwprintw( stats_window, NWIPE_GUI_STATS_THROUGHPUT_Y, NWIPE_GUI_STATS_THROUGHPUT_X, "Throughput:" );
/* Change the current time into a delta. */
nwipe_time_now -= nwipe_time_start;
mvwprintw(
stats_window, NWIPE_GUI_STATS_THROUGHPUT_Y, NWIPE_GUI_STATS_TAB, "%s/s", nomenclature_result_str );
/* Put the delta into HH:mm:ss form. */
nwipe_hh = nwipe_time_now / 3600;
nwipe_time_now %= 3600;
nwipe_mm = nwipe_time_now / 60;
nwipe_time_now %= 60;
nwipe_ss = nwipe_time_now;
/* Change the current time into a delta. */
nwipe_time_now -= nwipe_time_start;
/* Put the delta into HH:mm:ss form. */
nwipe_hh = nwipe_time_now / 3600;
nwipe_time_now %= 3600;
nwipe_mm = nwipe_time_now / 60;
nwipe_time_now %= 60;
nwipe_ss = nwipe_time_now;
/* Print the runtime. */
mvwprintw( stats_window, NWIPE_GUI_STATS_RUNTIME_Y, 1, "Runtime:" );
mvwprintw( stats_window,
NWIPE_GUI_STATS_RUNTIME_Y,
NWIPE_GUI_STATS_TAB,
"%02i:%02i:%02i",
nwipe_hh,
nwipe_mm,
nwipe_ss );
mvwprintw( stats_window, NWIPE_GUI_STATS_ETA_Y, 1, "Remaining:" );
time_t nwipe_maxeta = nwipe_misc_thread_data->maxeta;
if( nwipe_maxeta > 0 )
{
/* Do it again for the estimated runtime remaining. */
nwipe_hh = nwipe_maxeta / 3600;
nwipe_maxeta %= 3600;
nwipe_mm = nwipe_maxeta / 60;
nwipe_maxeta %= 60;
nwipe_ss = nwipe_maxeta;
/* Print the estimated runtime remaining. */
/* Print the runtime. */
mvwprintw( stats_window, NWIPE_GUI_STATS_RUNTIME_Y, 1, "Runtime:" );
mvwprintw( stats_window,
NWIPE_GUI_STATS_ETA_Y,
NWIPE_GUI_STATS_RUNTIME_Y,
NWIPE_GUI_STATS_TAB,
"%02i:%02i:%02i",
nwipe_hh,
nwipe_mm,
nwipe_ss );
}
/* Print the error count. */
mvwprintw( stats_window, NWIPE_GUI_STATS_ERRORS_Y, NWIPE_GUI_STATS_ERRORS_X, "Errors:" );
mvwprintw(
stats_window, NWIPE_GUI_STATS_ERRORS_Y, NWIPE_GUI_STATS_TAB, " %llu", nwipe_misc_thread_data->errors );
mvwprintw( stats_window, NWIPE_GUI_STATS_ETA_Y, 1, "Remaining:" );
/* Add a border. */
box( stats_window, 0, 0 );
time_t nwipe_maxeta = nwipe_misc_thread_data->maxeta;
if( nwipe_maxeta > 0 )
{
/* Do it again for the estimated runtime remaining. */
nwipe_hh = nwipe_maxeta / 3600;
nwipe_maxeta %= 3600;
nwipe_mm = nwipe_maxeta / 60;
nwipe_maxeta %= 60;
nwipe_ss = nwipe_maxeta;
/* Add a title. */
mvwprintw( stats_window, 0, ( NWIPE_GUI_STATS_W - strlen( stats_title ) ) / 2, "%s", stats_title );
/* Print the estimated runtime remaining. */
mvwprintw( stats_window,
NWIPE_GUI_STATS_ETA_Y,
NWIPE_GUI_STATS_TAB,
"%02i:%02i:%02i",
nwipe_hh,
nwipe_mm,
nwipe_ss );
}
/* Refresh internal representation of stats window */
wnoutrefresh( stats_window );
/* Print the error count. */
mvwprintw( stats_window, NWIPE_GUI_STATS_ERRORS_Y, NWIPE_GUI_STATS_ERRORS_X, "Errors:" );
mvwprintw( stats_window,
NWIPE_GUI_STATS_ERRORS_Y,
NWIPE_GUI_STATS_TAB,
" %llu",
nwipe_misc_thread_data->errors );
/* Output all windows to screen */
doupdate();
/* Add a border. */
box( stats_window, 0, 0 );
} // end blank screen if
/* Add a title. */
mvwprintw( stats_window, 0, ( NWIPE_GUI_STATS_W - strlen( stats_title ) ) / 2, "%s", stats_title );
/* Refresh internal representation of stats window */
wnoutrefresh( stats_window );
/* Output all windows to screen */
doupdate();
} // end blank screen if
} // end wipes have started if
} /* End of while loop */
if( nwipe_options.logfile[0] == '\0' )
{
nwipe_gui_title( footer_window, wipes_finished_footer );
}
else
{
char finish_message[NWIPE_GUI_FOOTER_W];
snprintf( finish_message,
sizeof( finish_message ),
"Wipe finished - press enter to exit. Logged to %s",
nwipe_options.logfile );
nwipe_gui_title( footer_window, finish_message );
}
nwipe_gui_title( footer_window, finish_message );
terminate_signal = 1;
return NULL;

View File

@@ -464,10 +464,13 @@ int hpa_dco_status( nwipe_context_t* ptr )
nwipe_log( NWIPE_LOG_INFO, "DCO Real max sectors not found" );
}
nwipe_log( NWIPE_LOG_INFO,
"libata: apparent max sectors reported as %lli on %s",
c->device_size_in_sectors,
c->device_name );
nwipe_log(
NWIPE_LOG_INFO,
"libata: apparent max sectors reported as %lli with sector size as %i/%i (logical/physical) on %s",
c->device_size_in_sectors,
c->device_sector_size, // logical
c->device_phys_sector_size, // physical
c->device_name );
/* close */
r = pclose( fp );
@@ -553,8 +556,8 @@ int hpa_dco_status( nwipe_context_t* ptr )
#endif
/* If any of the HPA or DCO values are larger than the apparent size then HPA is enabled. */
if( /*c->HPA_reported_set > c->device_size_in_sectors || */ c->HPA_reported_real > c->device_size_in_sectors
|| c->DCO_reported_real_max_sectors > c->device_size_in_sectors )
if( /*c->HPA_reported_set > c->device_size_in_sectors || */ c->HPA_reported_real > c->device_size_in_512byte_sectors
|| c->DCO_reported_real_max_sectors > c->device_size_in_512byte_sectors )
{
c->HPA_status = HPA_ENABLED;
nwipe_log( NWIPE_LOG_WARNING, " *********************************" );
@@ -602,7 +605,7 @@ int hpa_dco_status( nwipe_context_t* ptr )
/* If the DCO is reporting a real max sectors > the apparent size
* as reported by libata then that is what we will use as the real disc size
*/
if( c->DCO_reported_real_max_size > c->device_size_in_sectors )
if( c->DCO_reported_real_max_size > c->device_size_in_512byte_sectors )
{
c->Calculated_real_max_size_in_bytes = c->DCO_reported_real_max_sectors * c->device_sector_size;
}
@@ -612,13 +615,13 @@ int hpa_dco_status( nwipe_context_t* ptr )
* is the value we need, however if that is zero, then c->HPA_reported_set and if that is zero then
* c->device_size as reported by libata
*/
if( c->HPA_reported_real > c->device_size_in_sectors )
if( c->HPA_reported_real > c->device_size_in_512byte_sectors )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_real * c->device_sector_size;
}
else
{
if( c->HPA_reported_set > c->device_size_in_sectors )
if( c->HPA_reported_set > c->device_size_in_512byte_sectors )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_set * c->device_sector_size;
}
@@ -674,6 +677,7 @@ int hpa_dco_status( nwipe_context_t* ptr )
"c->DCO_reported_real_max_size=%lli, c->DCO_reported_real_max_sectors=%lli, c->HPA_sectors=%lli, "
"c->HPA_reported_set=%lli, c->HPA_reported_real=%lli, c->device_type=%i, "
"libata:c->device_size_in_sectors=%lli ",
"libata:c->device_size_in_512byte_sectors=%lli ",
c->Calculated_real_max_size_in_bytes,
c->device_size,
c->device_sector_size,
@@ -683,7 +687,8 @@ int hpa_dco_status( nwipe_context_t* ptr )
c->HPA_reported_set,
c->HPA_reported_real,
c->device_type,
c->device_size_in_sectors );
c->device_size_in_sectors,
c->device_size_in_512byte_sectors );
return set_return_value;
}
@@ -717,6 +722,9 @@ u64 nwipe_read_dco_real_max_sectors( char* device )
unsigned char buffer[LBA_SIZE]; // Received data block
unsigned char sense_buffer[SENSE_BUFFER_SIZE]; // Sense data
/* Zero the data block prior to use */
memset( buffer, 0, LBA_SIZE );
/* three characters represent one byte of sense data, i.e
* two characters and a space "01 AE 67"
*/

View File

@@ -666,7 +666,7 @@ void nwipe_log_summary( nwipe_context_t** ptr, int nwipe_selected )
// char duration[5];
char duration[314];
char model[18];
char serial_no[20];
char serial_no[NWIPE_SERIALNUMBER_LENGTH + 1];
char exclamation_flag[2];
int hours;
int minutes;
@@ -875,7 +875,8 @@ void nwipe_log_summary( nwipe_context_t** ptr, int nwipe_selected )
model[17] = 0;
/* Serial No. */
strncpy( serial_no, c[i]->device_serial_no, 20 );
strncpy( serial_no, c[i]->device_serial_no, NWIPE_SERIALNUMBER_LENGTH );
serial_no[NWIPE_SERIALNUMBER_LENGTH] = 0;
model[17] = 0;
nwipe_log( NWIPE_LOG_NOTIMESTAMP,
@@ -891,7 +892,8 @@ void nwipe_log_summary( nwipe_context_t** ptr, int nwipe_selected )
serial_no );
/* Create the PDF report/certificate */
if( strcmp( nwipe_options.PDFreportpath, "noPDF" ) != 0 )
if( nwipe_options.PDF_enable == 1 )
// if( strcmp( nwipe_options.PDFreportpath, "noPDF" ) != 0 )
{
/* to have some progress indication. can help if there are many/slow disks */
fprintf( stderr, "." );

View File

@@ -1,16 +1,16 @@
/*
This code is modified for use in nwipe.
/*
This code is modified for use in nwipe.
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -48,77 +48,89 @@
#include <stdio.h>
#include "mt19937ar-cok.h"
/* initializes state[N] with a seed */
void init_genrand( twister_state_t* state, unsigned long s)
/* initializes state[MT_STATE_SIZE] with a seed */
void init_genrand( twister_state_t* state, unsigned long s )
{
int j;
state->array[0]= s & 0xffffffffUL;
for( j = 1; j < N; j++ )
{
state->array[j] = (1812433253UL * (state->array[j-1] ^ (state->array[j-1] >> 30)) + j);
state->array[j] &= 0xffffffffUL; /* for >32 bit machines */
}
state->left = 1;
state->initf = 1;
int j;
state->array[0] = s & 0xffffffffUL;
for( j = 1; j < MT_STATE_SIZE; j++ )
{
state->array[j] = ( 1812433253UL * ( state->array[j - 1] ^ ( state->array[j - 1] >> 30 ) ) + j );
state->array[j] &= 0xffffffffUL; /* for >32 bit machines */
}
state->left = 1;
state->initf = 1;
}
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length )
{
int i = 1;
int j = 0;
int k = ( N > key_length ? N : key_length );
int j = 0;
int k = ( MT_STATE_SIZE > key_length ? MT_STATE_SIZE : key_length );
init_genrand( state, 19650218UL );
for( ; k; k-- )
{
state->array[i] = (state->array[i] ^ ((state->array[i-1] ^ (state->array[i-1] >> 30)) * 1664525UL)) + init_key[j] + j;
state->array[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
++i;
++j;
{
state->array[i] = ( state->array[i] ^ ( ( state->array[i - 1] ^ ( state->array[i - 1] >> 30 ) ) * 1664525UL ) )
+ init_key[j] + j;
state->array[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
++i;
++j;
if ( i >= N )
{
state->array[0] = state->array[N-1];
i = 1;
}
if( i >= MT_STATE_SIZE )
{
state->array[0] = state->array[MT_STATE_SIZE - 1];
i = 1;
}
if ( j >= key_length )
{
j = 0;
}
if( j >= key_length )
{
j = 0;
}
}
for( k = N -1; k; k-- )
{
state->array[i] = (state->array[i] ^ ((state->array[i-1] ^ (state->array[i-1] >> 30)) * 1566083941UL)) - i;
state->array[i] &= 0xffffffffUL;
++i;
for( k = MT_STATE_SIZE - 1; k; k-- )
{
state->array[i] =
( state->array[i] ^ ( ( state->array[i - 1] ^ ( state->array[i - 1] >> 30 ) ) * 1566083941UL ) ) - i;
state->array[i] &= 0xffffffffUL;
++i;
if ( i >= N )
{
state->array[0] = state->array[N-1];
i = 1;
}
if( i >= MT_STATE_SIZE )
{
state->array[0] = state->array[MT_STATE_SIZE - 1];
i = 1;
}
}
state->array[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
state->left = 1;
state->initf = 1;
state->array[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
state->left = 1;
state->initf = 1;
}
static void next_state( twister_state_t* state )
{
unsigned long *p = state->array;
unsigned long* p = state->array;
int j;
if( state->initf == 0) { init_genrand( state, 5489UL ); }
state->left = N;
// Ensures the generator is initialized
if( state->initf == 0 )
{
init_genrand( state, 5489UL );
}
state->left = MT_STATE_SIZE;
state->next = state->array;
for( j = N - M + 1; --j; p++ ) { *p = p[M] ^ TWIST(p[0], p[1]); }
for( j = M; --j; p++ ) { *p = p[M-N] ^ TWIST(p[0], p[1]); }
*p = p[M-N] ^ TWIST(p[0], state->array[0]);
for( j = MT_STATE_SIZE - MT_MIDDLE_WORD + 1; --j; p++ )
{
*p = p[MT_MIDDLE_WORD] ^ TWIST( p[0], p[1] );
}
for( j = MT_MIDDLE_WORD; --j; p++ )
{
*p = p[MT_MIDDLE_WORD - MT_STATE_SIZE] ^ TWIST( p[0], p[1] );
}
*p = p[MT_MIDDLE_WORD - MT_STATE_SIZE] ^ TWIST( p[0], state->array[0] );
}
/* generates a random number on [0,0xffffffff]-interval */
@@ -126,14 +138,18 @@ unsigned long twister_genrand_int32( twister_state_t* state )
{
unsigned long y;
if ( --state->left == 0 ) { next_state( state ); }
// Advance internal state if necessary
if( --state->left == 0 )
{
next_state( state );
}
y = *state->next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
// Tempering
y ^= ( y >> 11 );
y ^= ( y << 7 ) & 0x9d2c5680UL;
y ^= ( y << 15 ) & 0xefc60000UL;
y ^= ( y >> 18 );
return y;
}

View File

@@ -1,30 +1,29 @@
/*
* mt19937ar-cok.h: The Mersenne Twister PRNG implementation for nwipe.
*
* mt19937ar-cok.h: The Mersenne Twister PRNG implementation for nwipe.
*/
#ifndef MT19937AR_H_
#define MT19937AR_H_
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define MT_STATE_SIZE 624
#define MT_MIDDLE_WORD 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
#define MIXBITS( u, v ) ( ( (u) &UMASK ) | ( (v) &LMASK ) )
#define TWIST( u, v ) ( ( MIXBITS( u, v ) >> 1 ) ^ ( (v) &1UL ? MATRIX_A : 0UL ) )
typedef struct twister_state_t_
{
unsigned long array[N];
int left;
int initf;
unsigned long *next;
} twister_state_t;
unsigned long array[MT_STATE_SIZE]; // Updated to use MT_STATE_SIZE
int left;
int initf;
unsigned long* next;
} twister_state_t;
/* Initialize the MT state. ( 0 < key_length <= 624 ). */
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length);
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length );
/* Generate a random integer on the [0,0xffffffff] interval. */
unsigned long twister_genrand_int32( twister_state_t* state );

View File

@@ -542,7 +542,8 @@ int main( int argc, char** argv )
nwipe_log( NWIPE_LOG_NOTICE, "%s has serial number %s", c2[i]->device_name, c2[i]->device_serial_no );
}
/* Do sector size and block size checking. */
/* Do sector size and block size checking. I don't think this does anything useful as logical/Physical
* sector sizes are obtained by libparted in check.c */
if( ioctl( c2[i]->device_fd, BLKSSZGET, &c2[i]->device_sector_size ) == 0 )
{
@@ -737,32 +738,6 @@ int main( int argc, char** argv )
}
}
/* Kill the temperature update thread */
if( nwipe_temperature_thread )
{
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "Cancelling the temperature thread." );
}
/* We don't want to use pthread_cancel as our temperature thread is aware of the control-c
* signal and will exit itself we just join the temperature thread and wait for confirmation
*/
r = pthread_join( nwipe_temperature_thread, NULL );
if( r != 0 )
{
nwipe_log( NWIPE_LOG_WARNING,
"main()>pthread_join():Error when waiting for temperature thread to cancel." );
}
else
{
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "temperature thread has been cancelled" );
}
}
}
/* Release the gui. */
if( !nwipe_options.nogui )
{
@@ -839,6 +814,42 @@ int main( int argc, char** argv )
thread_timeout_counter--;
sleep( 1 );
}
/* Now all the wipe threads have finished, we can issue a terminate_signal = 1
* which will cause the temperature update thread to terminate, this is necessary
* because in gui mode the terminate_signal is set when the user presses a key to
* exit on completion of all the wipes, however in non gui mode that code isn't
* active (being in the gui section) so here we need to set the terminate signal
* specifically for a completed wipes/s just for non gui mode.
*/
terminate_signal = 1;
/* Kill the temperature update thread */
if( nwipe_temperature_thread )
{
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "Cancelling the temperature thread." );
}
/* We don't want to use pthread_cancel as our temperature thread is aware of the control-c
* signal and will exit itself we just join the temperature thread and wait for confirmation
*/
r = pthread_join( nwipe_temperature_thread, NULL );
if( r != 0 )
{
nwipe_log( NWIPE_LOG_WARNING,
"main()>pthread_join():Error when waiting for temperature thread to cancel." );
}
else
{
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_INFO, "temperature thread has been cancelled" );
}
}
}
if( nwipe_options.verbose )
{
for( i = 0; i < nwipe_selected; i++ )

View File

@@ -42,6 +42,8 @@ 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_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/* The getopt() result holder. */
int nwipe_opt;
@@ -127,8 +129,9 @@ int nwipe_options_parse( int argc, char** argv )
/* Set default options. */
nwipe_options.autonuke = 0;
nwipe_options.autopoweroff = 0;
nwipe_options.method = &nwipe_dodshort;
nwipe_options.prng = ( sizeof( unsigned long int ) >= 8 ) ? &nwipe_isaac64 : &nwipe_isaac;
nwipe_options.method = &nwipe_random;
nwipe_options.prng =
( sizeof( unsigned long int ) >= 8 ) ? &nwipe_xoroshiro256_prng : &nwipe_add_lagg_fibonacci_prng;
nwipe_options.rounds = 1;
nwipe_options.noblank = 0;
nwipe_options.nousb = 0;
@@ -398,6 +401,23 @@ int nwipe_options_parse( int argc, char** argv )
nwipe_options.PDFreportpath[strlen( optarg )] = '\0';
strncpy( nwipe_options.PDFreportpath, optarg, sizeof( nwipe_options.PDFreportpath ) );
/* Command line options will override what's in nwipe.conf */
if( strcmp( nwipe_options.PDFreportpath, "noPDF" ) == 0 )
{
nwipe_options.PDF_enable = 0;
nwipe_conf_update_setting( "PDF_Certificate.PDF_Enable", "DISABLED" );
}
else
{
if( strcmp( nwipe_options.PDFreportpath, "." ) )
{
/* and if the user has specified a PDF path then enable PDF */
nwipe_options.PDF_enable = 1;
nwipe_conf_update_setting( "PDF_Certificate.PDF_Enable", "ENABLED" );
}
}
break;
case 'e': /* exclude drives option */
@@ -473,6 +493,16 @@ int nwipe_options_parse( int argc, char** argv )
nwipe_options.prng = &nwipe_isaac64;
break;
}
if( strcmp( optarg, "add_lagg_fibonacci_prng" ) == 0 )
{
nwipe_options.prng = &nwipe_add_lagg_fibonacci_prng;
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 );
@@ -522,6 +552,8 @@ 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_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/**
* Prints a manifest of options to the log.
@@ -575,19 +607,33 @@ void nwipe_options_log( void )
}
else
{
if( nwipe_options.prng == &nwipe_isaac )
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac" );
nwipe_log( NWIPE_LOG_NOTICE, " prng = Lagged Fibonacci generator (EXPERIMENTAL!)" );
}
else
{
if( nwipe_options.prng == &nwipe_isaac64 )
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac64" );
nwipe_log( NWIPE_LOG_NOTICE, " prng = XORoshiro-256 (EXPERIMENTAL!)" );
}
else
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Undefined" );
if( nwipe_options.prng == &nwipe_isaac )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac" );
}
else
{
if( nwipe_options.prng == &nwipe_isaac64 )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac64" );
}
else
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Undefined" );
}
}
}
}
}
@@ -649,7 +695,10 @@ void display_help()
puts( " (default: last)" );
puts( " off - Do not verify" );
puts( " last - Verify after the last pass" );
puts( " all - Verify every pass\n" );
puts( " all - Verify every pass" );
puts( " " );
puts( " Please mind that HMG IS5 enhanced always verifies the" );
puts( " last (PRNG) pass regardless of this option.\n" );
puts( " -m, --method=METHOD The wiping method. See man page for more details." );
puts( " (default: dodshort)" );
puts( " dod522022m / dod - 7 pass DOD 5220.22-M method" );
@@ -660,11 +709,12 @@ void display_help()
puts( " zero / quick - Overwrite with zeros" );
puts( " one - Overwrite with ones (0xFF)" );
puts( " verify_zero - Verifies disk is zero filled" );
puts( " verify_one - Verifies disk is 0xFF filled\n" );
puts( " verify_one - Verifies disk is 0xFF filled" );
puts( " is5enh - HMG IS5 enhanced\n" );
puts( " -l, --logfile=FILE Filename to log to. Default is STDOUT\n" );
puts( " -P, --PDFreportpath=PATH Path to write PDF reports to. Default is \".\"" );
puts( " If set to \"noPDF\" no PDF reports are written.\n" );
puts( " -p, --prng=METHOD PRNG option (mersenne|twister|isaac|isaac64)\n" );
puts( " -p, --prng=METHOD PRNG option (mersenne|twister|isaac|isaac64|add_lagg_fibonacci_prng)\n" );
puts( " -q, --quiet Anonymize logs and the GUI by removing unique data, i.e." );
puts( " serial numbers, LU WWN Device ID, and SMBIOS/DMI data" );
puts( " XXXXXX = S/N exists, ????? = S/N not obtainable\n" );

View File

@@ -324,7 +324,7 @@ int nwipe_random_pass( NWIPE_METHOD_SIGNATURE )
/* For the first block only, check the prng actually wrote something to the buffer */
if( z == c->device_size )
{
idx = c->device_stat.st_blksize;
idx = c->device_stat.st_blksize - 1;
while( idx > 0 )
{
if( b[idx] != 0 )

View File

@@ -25,12 +25,21 @@
#include "mt19937ar-cok/mt19937ar-cok.h"
#include "isaac_rand/isaac_rand.h"
#include "isaac_rand/isaac64.h"
#include "alfg/add_lagg_fibonacci_prng.h" //Lagged Fibonacci generator prototype
#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 };
/* ALFG PRNG Structure */
nwipe_prng_t nwipe_add_lagg_fibonacci_prng = { "Lagged Fibonacci generator",
nwipe_add_lagg_fibonacci_prng_init,
nwipe_add_lagg_fibonacci_prng_read };
/* 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. */
static inline void u32_to_buffer( u8* restrict buffer, u32 val, const int len )
{
@@ -250,3 +259,85 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE )
return 0;
}
/* EXPERIMENTAL implementation of Lagged Fibonacci generator a lot of random numbers */
int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE )
{
if( *state == NULL )
{
nwipe_log( NWIPE_LOG_NOTICE, "Initialising Lagged Fibonacci generator PRNG" );
*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 ) );
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_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE )
{
u8* restrict bufpos = buffer;
size_t words = count / SIZE_OF_ADD_LAGG_FIBONACCI_PRNG;
/* Loop to fill the buffer with blocks directly from the Fibonacci algorithm */
for( size_t ii = 0; ii < words; ++ii )
{
add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, bufpos );
bufpos += SIZE_OF_ADD_LAGG_FIBONACCI_PRNG; // Move to the next block
}
/* Handle remaining bytes if count is not a multiple of SIZE_OF_ADD_LAGG_FIBONACCI_PRNG */
const size_t remain = count % SIZE_OF_ADD_LAGG_FIBONACCI_PRNG;
if( remain > 0 )
{
unsigned char temp_output[16]; // Temporary buffer for the last block
add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, temp_output );
// Copy the remaining bytes
memcpy( bufpos, temp_output, remain );
}
return 0; // Success
}
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
}

View File

@@ -55,6 +55,14 @@ int nwipe_isaac_read( NWIPE_PRNG_READ_SIGNATURE );
int nwipe_isaac64_init( NWIPE_PRNG_INIT_SIGNATURE );
int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE );
/* ALFG prototypes. */
int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE );
int nwipe_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE );
/* XOROSHIRO-256 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 +70,10 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE );
#define SIZE_OF_ISAAC 4
#define SIZE_OF_ISAAC64 8
/* Size of the Lagged Fibonacci generator is not derived from the architecture, but it is strictly 32 bytes */
#define SIZE_OF_ADD_LAGG_FIBONACCI_PRNG 32
/* 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_ */

View File

@@ -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 <stdio.h>

View File

@@ -4,14 +4,14 @@
* used by configure to dynamically assign those values
* to documentation files.
*/
const char* version_string = "0.35";
const char* version_string = "0.37";
const char* program_name = "nwipe";
const char* author_name = "Martijn van Brummelen";
const char* email_address = "git@brumit.nl";
const char* years = "2023";
const char* years = "2024";
const char* copyright = "Copyright Darik Horn <dajhorn-dban@vanadac.com>\n\
Modifications to original dwipe Copyright Andy Beverley <andy@andybev.com>\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\
FOR A PARTICULAR PURPOSE.\n";
const char* banner = "nwipe 0.35";
const char* banner = "nwipe 0.37";

View File

@@ -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 <stdint.h>
#include <string.h>
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'
}

View File

@@ -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 <stdint.h>
// 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