mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-21 22:42:29 +00:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
051e1aa0c9 | ||
|
|
9856cecd45 | ||
|
|
e8297c642a | ||
|
|
bb7a251349 | ||
|
|
8a44ca947f | ||
|
|
270d643044 | ||
|
|
618a8d6894 | ||
|
|
6e4ca14770 | ||
|
|
523ebc470a | ||
|
|
a41d03125c | ||
|
|
a9e3dd2a77 | ||
|
|
e3dfa55356 | ||
|
|
5bdd87f85e | ||
|
|
3846e1e1aa | ||
|
|
c7155bf514 | ||
|
|
deaae2b9c1 | ||
|
|
1691abdb0b | ||
|
|
c837e943d7 | ||
|
|
5506c76b65 | ||
|
|
53383285de | ||
|
|
8a93e8856d | ||
|
|
0fbc1ab991 | ||
|
|
710478d6fd | ||
|
|
1511791a25 | ||
|
|
f250aee28d | ||
|
|
afdbdb7ee8 | ||
|
|
4278f69640 | ||
|
|
2e6ce1630d | ||
|
|
c024addd93 | ||
|
|
d1edd0570a | ||
|
|
af41c9739f | ||
|
|
97deed81db | ||
|
|
ddc63538b7 | ||
|
|
28271712db | ||
|
|
ef312ff90d | ||
|
|
6d6b7ac8c1 | ||
|
|
5140f92077 | ||
|
|
4893fa7ea0 | ||
|
|
b83423a424 | ||
|
|
4394f24245 | ||
|
|
1ae76b5774 | ||
|
|
fca8937f26 | ||
|
|
09d620c9c7 | ||
|
|
f0ed2fe7f0 | ||
|
|
9400ff5219 | ||
|
|
81fc479239 | ||
|
|
28095801ac | ||
|
|
66a951722d | ||
|
|
834348c8c8 | ||
|
|
e4a51c00c1 | ||
|
|
00bcce475b | ||
|
|
0114ccf937 | ||
|
|
616a2ab236 | ||
|
|
e6e638c4dc | ||
|
|
8ad4fe200d | ||
|
|
a4ce92be6f | ||
|
|
e851769025 | ||
|
|
c7ada53d4e | ||
|
|
bb93793d7f | ||
|
|
ea386f35e7 | ||
|
|
204a82f6f0 | ||
|
|
f66d838b23 | ||
|
|
4fad31ec50 | ||
|
|
0e03653ab5 | ||
|
|
4e29f6c514 | ||
|
|
d40c28bfc5 | ||
|
|
0d0150393c | ||
|
|
238656a5b4 | ||
|
|
a2d998d7c3 | ||
|
|
a89dc8b9e9 | ||
|
|
87376a0bbb | ||
|
|
201eb565f9 | ||
|
|
50bcf81ea6 | ||
|
|
5e532c9367 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,3 +20,4 @@ src/Makefile
|
||||
src/Makefile.in
|
||||
src/nwipe
|
||||
stamp-h1
|
||||
.DS_Store
|
||||
|
||||
105
CHANGELOG.md
105
CHANGELOG.md
@@ -1,69 +1,91 @@
|
||||
RELEASE NOTES
|
||||
=============
|
||||
|
||||
v0.38
|
||||
-----------------------
|
||||
includes the following changes:
|
||||
|
||||
- Fixes type error, relevant to i686 (32 bit) only. Fixes a compile error on some distros. [#588](https://github.com/martijnvanbrummelen/nwipe/pull/588) Thanks @Knogle
|
||||
- Added feature relevant to ShredOS only, the f key will toggle the font size, standard size to double size, has no action for other xorg/wayland distributions. The f key is available in the drive selection and progress screens only. Note that in earlier commits in this release the d key was programmed however this is now the f key to toggle font size. [#589](https://github.com/martijnvanbrummelen/nwipe/pull/589) [#635](https://github.com/martijnvanbrummelen/nwipe/pull/635) Thanks @PartialVolume
|
||||
- Fixes a issue where SAS drives always respond with hidden sectors = ???, i.e warning. This patch fixes the problem so that a SAS drive responds with hidden sectors = not applicable. A SATA drive connected to a SAS interface should still respond with yes or no subject to the interface passing HPA and DCO-identify commands. [#605](https://github.com/martijnvanbrummelen/nwipe/pull/605) Thanks @PartialVolume
|
||||
- On some distros, nwipe may not be able to find hdparm or smartctl even when they are installed. This is due to a symbolic link issue with the distro. The patch fixes this issue by adding a new search location when looking for hdparm and smartctl. The new search location is /usr/sbin/. Previously we searched /sbin/ and /usr/bin/ but /sbin is symbolically linked to /usr/sbin/ so just in case there was some issue with the symbolic link we also now search /usr/sbin/ [#606](https://github.com/martijnvanbrummelen/nwipe/pull/606) Thanks @PartialVolume
|
||||
- The hidden sector check for SAS drives has been disabled as it is believed that SAS drives do not support the SCSI commands to adjust the drives size as reported to the O.S. [#607](https://github.com/martijnvanbrummelen/nwipe/pull/607) Thanks @PartialVolume
|
||||
- Some USB adapters report the model name and serial number with the incorrect endian, so adjacent characters in the model name are swapped with each other. This patch detects and fixes model names for Hitachi, Toshiba, WDC Western Digital Corporation and Seagate/ST drives. Mainly some older adapters and drive interfaces might have this issue. [#630](https://github.com/martijnvanbrummelen/nwipe/pull/630) Thanks @PartialVolume
|
||||
- Fixes the `s shift s bug` as reported here https://github.com/PartialVolume/shredos.x86_64/issues/301 To summarize, if no drives are selected and then the user presses s (lower case) a warning appears indicating that the user should press S (upper case) to start the wipe. This warning appears for about 3 seconds but during this time if the user presses S (upper case) nwipe would immediately complete, having wiped no drives and requesting the user to press the spacebar to exit. The is incorrect behaviour.
|
||||
The bug doesn't appear if the user pressed S after the 3 seconds elapsed and the warning message disappeared. This patch fixes this so that it does not exit but displays the warning for 3 seconds and then waits for input. [#636](https://github.com/martijnvanbrummelen/nwipe/pull/636)
|
||||
|
||||
v0.37
|
||||
-----------------------
|
||||
includes the following changes:
|
||||
|
||||
- Added the XORoshiro-256 pseudo random number generator (PRNG). Thanks to Fabian Druschke @knogle [#555](https://github.com/martijnvanbrummelen/nwipe/pull/555)
|
||||
- Added the Lagged Fibonacci PRNG generator. Thanks again to Fabian Druschke @knogle [#556](https://github.com/martijnvanbrummelen/nwipe/pull/556)
|
||||
- Added missing help for HMG IS5 enhanced. Thanks to @AndCycle [#569](https://github.com/martijnvanbrummelen/nwipe/pull/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](https://github.com/martijnvanbrummelen/nwipe/pull/574)
|
||||
- Minor change to nwipe's man page filename, nwipe.1 to nwipe.8 to fix a Debian warning. [#577](https://github.com/martijnvanbrummelen/nwipe/pull/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
|
||||
|
||||
- Added the abbreviation MMC for mmcblk devices such as SD and microSD cards and some low budget laptops. [#526](https://github.com/martijnvanbrummelen/nwipe/pull/526)
|
||||
- Fixed some serial numbers that were displaying garbage. [#527](https://github.com/martijnvanbrummelen/nwipe/pull/527)
|
||||
- Fixed auto power off and nowait when the screen has been blanked by the user. [#529](https://github.com/martijnvanbrummelen/nwipe/pull/529)
|
||||
- Fixed nwipe not auto exiting on completion when in non gui mode. [#531](https://github.com/martijnvanbrummelen/nwipe/pull/531)
|
||||
- Fixed smart page titles so they have a consistent format with page 1 in the PDF report. [#532](https://github.com/martijnvanbrummelen/nwipe/pull/532)
|
||||
- Fixed some of the config help messages that displayed incorrect information. [#533](https://github.com/martijnvanbrummelen/nwipe/pull/533)
|
||||
- Inserted a space between temperature and model. [#534](https://github.com/martijnvanbrummelen/nwipe/pull/534)
|
||||
- Fixed incorrect footer on return to organisation/customer preview screen. [#535](https://github.com/martijnvanbrummelen/nwipe/pull/535)
|
||||
- Made footer completion message more informative. [#538](https://github.com/martijnvanbrummelen/nwipe/pull/538)
|
||||
- Fixed hidden sector detection for devices with logical/physical size of 4096/4096. [#543](https://github.com/martijnvanbrummelen/nwipe/pull/543) [#546](https://github.com/martijnvanbrummelen/nwipe/pull/546)
|
||||
- Fixed some strcpy compiler warnings. [#548](https://github.com/martijnvanbrummelen/nwipe/pull/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.
|
||||
- Nwipe now supports HPA/DCO detection, aka hidden sector detection. This is where the drive has been configured to report a smaller size to the operating system (O.S.) than it actually is. The HPA/DCO status is reported on the main drive selection screen as [HS? N/A] for drive that does not support HPA/DCO such as NvMe. [HS? YES] for a drive that is reporting a size smaller than it actually is, i.e has hidden sectors and [HS? NO] where the drive is reporting it's actual size correctly to the O.S. And finally [HS? ???] where nwipe cannot determine the HPA/DCO status as the drive is not responding to the ATA commands used to detect HPA/DCO. This might be because the drive does not support HPA/DCO or the interface adapter does not support ATA passthrough as is the case with a lot of the USB adapters on the market, but not all USB adapters. Nwipe does not currently allow removal of the HPA/DCO so you will still need to use hdparm to reset the drive so it reports its correct size before using nwipe to wipe the drive. HPA/DCO reset may be added in the next version. Thanks to @mdcato for the help testing the code and HPA/DCO results as displayed in the report.
|
||||
- This bug only applies to ones wipe and one or zero's verification. A very rare occurrence of a incorrect percentage on completion. The actual wipe was completed correctly it was just that the percentage calculation was wrong. #459
|
||||
- This bug only applies to ones wipe and one or zero's verification. A very rare occurrence of a incorrect percentage on completion. The actual wipe was completed correctly it was just that the percentage calculation was wrong. [#459](https://github.com/martijnvanbrummelen/nwipe/pull/459)
|
||||
- Nwipe now supports a configuration file /etc/nwipe/nwipe.conf. Currently it supports settings related to the PDF certificate but more options will be added in the future.
|
||||
- If you are running nwipe within the KDE konsole terminal and you resize the window by pulling on the corners, occasionally nwipe will exit with the error message: "GUI.c,nwipe_gui_select(), loop runaway, did you close the terminal without exiting nwipe? Initiating shutdown now" The loop runaway detection has been made less sensitive, i.e 32 iterations per second of the GUI update can now be completed before a loop runaway is detected. previously it was 8. In practise when sizing the konsole window, anywhere between 1 and 17 iterations will occur.#467
|
||||
- If you are running nwipe within the KDE konsole terminal and you resize the window by pulling on the corners, occasionally nwipe will exit with the error message: "GUI.c,nwipe_gui_select(), loop runaway, did you close the terminal without exiting nwipe? Initiating shutdown now" The loop runaway detection has been made less sensitive, i.e 32 iterations per second of the GUI update can now be completed before a loop runaway is detected. previously it was 8. In practise when sizing the konsole window, anywhere between 1 and 17 iterations will occur. [#467](https://github.com/martijnvanbrummelen/nwipe/pull/467)
|
||||
- Nwipe now provides better temperature support for SAS drives. Thanks to @ggruber for all the code and testing he contributed.
|
||||
- Disc sizes are now shown differently to provide more information about their size. For instance a 1.2TB drive was shown as 1TB, now it is shown as 1200GB. Thanks to @ggruber for his code contribution.
|
||||
- Interface/bustype type was reported as UNK fo SAS drives, now reported correctly as SAS. Thanks to @ggruber for his code contribution.
|
||||
- Interface/bustype type has been enhanced to show SAS-SSD when a SSD drive is present. Thanks to @ggruber for his code contribution.
|
||||
- Nwipe's 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.
|
||||
|
||||
v0.34
|
||||
-----------------------
|
||||
- Fix a compiler warning -Wformat-zero-length string
|
||||
|
||||
|
||||
v0.33
|
||||
-----------------------
|
||||
- Fixes a slight screen corruption on 80 column display. When highlighting the verify ones option the first two digits of DoD 5220.20-M disappear. This patch fixes that issue.@PartialVolume #348
|
||||
- For some controllers/drivers the readlink method of obtaining the bus type for GUI display does not work. If we haven't already resolved the bus type, we then also check smartctl for the transport protocol for SAS. @PartialVolume #350
|
||||
- Check smartctl for unresolved bus types SATA @PartialVolume #358
|
||||
- Changed message from (No ATA pass-thru) to (S/N: unknown) as the reason the serial number is unknown is because there is no ATA pass through for the chipset being used by the USB to SATA adapter, basically we are making the message more meaningful for the end user rather than for the engineer/programmer that may understand the previous terminology used. @PartialVolume @Firminator #356
|
||||
- Add drive temperature monitoring and display temperature in degrees Celsius in the GUI. Requires the kernel drivetemp module and makes use of the hwmon sub system in the kernel to extract drive temperatures. Nwipe will automatically load the drivetemp module if it's available. @PartialVolume #360 #361 #364
|
||||
- Remove /dev/ from gui for long device names. This fixes column alignment issues in the gui with nvme drives i.e. nvme0n1 etc. If the drive name including path exceeds 8 characters the /dev/ is removed and prefixed with spaces to a total max length of 8 characters. @PartialVolume #365
|
||||
- Add -q --quiet option - anonymize serial numbers and SMBIOS-DMI data. This anonymizes serial numbers and related identifiable information for drives and hardware but does not remove model information in both the GUI and the log displayed by stdout at the end of a wipe and also in the log file if enabled in options. This feature is useful for uploading logs when submitting bug reports. @PartialVolume #366 #367 #371 #379 #383
|
||||
- Fixes a intermittent FAILED message that is displayed in the summary table when the message should have been UABORTED. The incorrect FAILED message only occurred when using control-C to abort a wipe. @PartialVolume #373
|
||||
- When many verification or pass errors are detected the status line can wrap on a 80 column display. This patch makes the error message more succinct which will free up about 10 characters & prevents the line wrapping. @PartialVolume #374
|
||||
- Fixes a problem that occurs with a unresponsive drive that causes the ETA to grow to an enormous value. We now do not calculate an individual drives ETA when the throughput of the drive is zero so avoiding the overall ETA being incorrect for drives that are working correctly when multiple drives are being simultaneously wiped. While a individual drives ETA is calculated it is not displayed but only used to determine the overall ETA when all drives have completed. @PartialVolume #375
|
||||
- Add temperature monitoring and display with NVMe drives. @PartialVolume #377 #380 #381
|
||||
- When one of the two verify only methods are selected change the drive selected text from WIPE to VRFY to indicate the drive is not being wiped, but is only being verified. @PartialVolume #378
|
||||
- Fixes a incorrect sector, block and device sizes in 32 bit builds only as displayed in the nwipe log. This problem had no affect on the wipe as the issue was caused by a incorrect format specifier that affected the log text only. @PartialVolume #387 #388
|
||||
- Fixes a issue where temperatures may not have been available on Debian systems due to the location of modprobe. Particularly relevant to Debian which when logged in as root doesn't put /sbin in the $PATH environment setting. This issue was not necessarily relevant for Linux distros based on Debian, for instance, Ubuntu where nwipe would have found the modprobe command. @PartialVolume #390 #391
|
||||
- Improve wipe thread cancellation error checking. @PartialVolume #392
|
||||
- Improve GUI thread messaging if a pthread_join fails. @PartialVolume #393
|
||||
- Fixed a missing serial number on SAS drive.@PartialVolume #394
|
||||
- Added ISAAC-64 for 64 bit systems. Thanks @chkboom #398 #401
|
||||
- Fixes a problem with the Gutmann wipe where the random passes at the beginning and end were being re-arranged when only the inner passes should be rearranged. Thanks @chkboom #399
|
||||
- Fixes a obscure incorrect summary table status, while the log text correctly reports the failure. If the drive becomes non responsive during the wipe, the MB/s throughput will slowly drop towards 0MB/s and will display a FAILURE -1 error. The logs will correctly display errors and nwipe's return status will be non zero, however the summary table may display erased rather than FAILURE, this is because
|
||||
- Fixes a slight screen corruption on 80 column display. When highlighting the verify ones option the first two digits of DoD 5220.20-M disappear. This patch fixes that issue.@PartialVolume [#348](https://github.com/martijnvanbrummelen/nwipe/pull/348)
|
||||
- For some controllers/drivers the readlink method of obtaining the bus type for GUI display does not work. If we haven't already resolved the bus type, we then also check smartctl for the transport protocol for SAS. @PartialVolume [#350](https://github.com/martijnvanbrummelen/nwipe/pull/350)
|
||||
- Check smartctl for unresolved bus types SATA @PartialVolume [#358](https://github.com/martijnvanbrummelen/nwipe/pull/358)
|
||||
- Changed message from (No ATA pass-thru) to (S/N: unknown) as the reason the serial number is unknown is because there is no ATA pass through for the chipset being used by the USB to SATA adapter, basically we are making the message more meaningful for the end user rather than for the engineer/programmer that may understand the previous terminology used. @PartialVolume @Firminator [#356](https://github.com/martijnvanbrummelen/nwipe/pull/356)
|
||||
- Add drive temperature monitoring and display temperature in degrees Celsius in the GUI. Requires the kernel drivetemp module and makes use of the hwmon sub system in the kernel to extract drive temperatures. Nwipe will automatically load the drivetemp module if it's available. @PartialVolume [#360](https://github.com/martijnvanbrummelen/nwipe/pull/360) [#361](https://github.com/martijnvanbrummelen/nwipe/pull/361) [#364](https://github.com/martijnvanbrummelen/nwipe/pull/364)
|
||||
- Remove /dev/ from gui for long device names. This fixes column alignment issues in the gui with nvme drives i.e. nvme0n1 etc. If the drive name including path exceeds 8 characters the /dev/ is removed and prefixed with spaces to a total max length of 8 characters. @PartialVolume [#365](https://github.com/martijnvanbrummelen/nwipe/pull/365)
|
||||
- Add -q --quiet option - anonymize serial numbers and SMBIOS-DMI data. This anonymizes serial numbers and related identifiable information for drives and hardware but does not remove model information in both the GUI and the log displayed by stdout at the end of a wipe and also in the log file if enabled in options. This feature is useful for uploading logs when submitting bug reports. @PartialVolume [#366](https://github.com/martijnvanbrummelen/nwipe/pull/366) [#367](https://github.com/martijnvanbrummelen/nwipe/pull/367) [#371](https://github.com/martijnvanbrummelen/nwipe/pull/371) [#379](https://github.com/martijnvanbrummelen/nwipe/pull/379) [#383](https://github.com/martijnvanbrummelen/nwipe/pull/383)
|
||||
- Fixes a intermittent FAILED message that is displayed in the summary table when the message should have been UABORTED. The incorrect FAILED message only occurred when using control-C to abort a wipe. @PartialVolume [#373](https://github.com/martijnvanbrummelen/nwipe/pull/373)
|
||||
- When many verification or pass errors are detected the status line can wrap on a 80 column display. This patch makes the error message more succinct which will free up about 10 characters & prevents the line wrapping. @PartialVolume [#374](https://github.com/martijnvanbrummelen/nwipe/pull/374)
|
||||
- Fixes a problem that occurs with a unresponsive drive that causes the ETA to grow to an enormous value. We now do not calculate an individual drives ETA when the throughput of the drive is zero so avoiding the overall ETA being incorrect for drives that are working correctly when multiple drives are being simultaneously wiped. While a individual drives ETA is calculated it is not displayed but only used to determine the overall ETA when all drives have completed. @PartialVolume [#375](https://github.com/martijnvanbrummelen/nwipe/pull/375)
|
||||
- Add temperature monitoring and display with NVMe drives. @PartialVolume [#377](https://github.com/martijnvanbrummelen/nwipe/pull/377) [#380](https://github.com/martijnvanbrummelen/nwipe/pull/380) [#381](https://github.com/martijnvanbrummelen/nwipe/pull/381)
|
||||
- When one of the two verify only methods are selected change the drive selected text from WIPE to VRFY to indicate the drive is not being wiped, but is only being verified. @PartialVolume [#378](https://github.com/martijnvanbrummelen/nwipe/pull/378)
|
||||
- Fixes a incorrect sector, block and device sizes in 32 bit builds only as displayed in the nwipe log. This problem had no affect on the wipe as the issue was caused by a incorrect format specifier that affected the log text only. @PartialVolume [#387](https://github.com/martijnvanbrummelen/nwipe/pull/387) [#388](https://github.com/martijnvanbrummelen/nwipe/pull/388)
|
||||
- Fixes a issue where temperatures may not have been available on Debian systems due to the location of modprobe. Particularly relevant to Debian which when logged in as root doesn't put /sbin in the $PATH environment setting. This issue was not necessarily relevant for Linux distros based on Debian, for instance, Ubuntu where nwipe would have found the modprobe command. @PartialVolume [#390](https://github.com/martijnvanbrummelen/nwipe/pull/390) [#391](https://github.com/martijnvanbrummelen/nwipe/pull/391)
|
||||
- Improve wipe thread cancellation error checking. @PartialVolume [#392](https://github.com/martijnvanbrummelen/nwipe/pull/392)
|
||||
- Improve GUI thread messaging if a pthread_join fails. @PartialVolume [#393](https://github.com/martijnvanbrummelen/nwipe/pull/393)
|
||||
- Fixed a missing serial number on SAS drive.@PartialVolume [#394](https://github.com/martijnvanbrummelen/nwipe/pull/394)
|
||||
- Added ISAAC-64 for 64 bit systems. Thanks @chkboom [#398](https://github.com/martijnvanbrummelen/nwipe/pull/398) [#401](https://github.com/martijnvanbrummelen/nwipe/pull/401)
|
||||
- Fixes a problem with the Gutmann wipe where the random passes at the beginning and end were being re-arranged when only the inner passes should be rearranged. Thanks @chkboom [#399](https://github.com/martijnvanbrummelen/nwipe/pull/399)
|
||||
- Fixes an obscure incorrect summary table status, while the log text correctly reports the failure. If the drive becomes non responsive during the wipe, the MB/s throughput will slowly drop towards 0MB/s and will display a FAILURE -1 error. The logs will correctly display errors and nwipe's return status will be non zero, however the summary table may display erased rather than FAILURE, this is because
|
||||
the wipe thread exited prematurely without setting the pass error. This fixes the error by checking the context's result status, i.e non zero on failure and if pass equals zero it makes pass equal to one. This is then picked up by the summary table log code which then marks the status
|
||||
correctly as FAILURE in the summary table. @PartialVolume #400
|
||||
- Fixes a spurious message on abort before wipe.This patch fixes a minor display issue that occurs when a user aborts a wipe before a wipe has started. It only occurs if the user had selected one or more drives for wipe and then aborted before starting the wipe. The spurious message only occurs in a virtual terminal, i.e. /dev/tty1, /dev/tty2, /dev/console It does not occur in terminal applications such as konsole, xterm, terminator etc. The spurious message that appears in the main window, states that "/dev/sdxyz 100% complete" along with garbage values in the statistics window. The message appears for a fraction of a second before being replaced with the textual log information that correctly states that the user aborted and no wipe was started. Basically the gui status information update function tries to update the data when the wipe hasn't even started. The fix is to only update the statistics information only if a wipe has started by checking the 'global_wipe_status' value which indicates whether any wipe started. '1' indicates that a wipe has started, else '0' if no wipe has started. @PartialVolume #406
|
||||
correctly as FAILURE in the summary table. @PartialVolume [#400](https://github.com/martijnvanbrummelen/nwipe/pull/400)
|
||||
- Fixes a spurious message on abort before wipe.This patch fixes a minor display issue that occurs when a user aborts a wipe before a wipe has started. It only occurs if the user had selected one or more drives for wipe and then aborted before starting the wipe. The spurious message only occurs in a virtual terminal, i.e. /dev/tty1, /dev/tty2, /dev/console It does not occur in terminal applications such as konsole, xterm, terminator etc. The spurious message that appears in the main window, states that "/dev/sdxyz 100% complete" along with garbage values in the statistics window. The message appears for a fraction of a second before being replaced with the textual log information that correctly states that the user aborted and no wipe was started. Basically the gui status information update function tries to update the data when the wipe hasn't even started. The fix is to only update the statistics information only if a wipe has started by checking the 'global_wipe_status' value which indicates whether any wipe started. '1' indicates that a wipe has started, else '0' if no wipe has started. @PartialVolume [#406](https://github.com/martijnvanbrummelen/nwipe/pull/406)
|
||||
- Fixes temperature update in drive selection window. This fixes a problem where the drive temperature is not updated
|
||||
automatically in only the drive selection window. The temperature is however updated correctly every 60 seconds during a wipe in the wipe status window. This bug would probably never be noticed by most people as usually the drive temperature changes slowly and only rises once a wipe has started. The only time I imagine it would have been noticed would have been if the drive temperature was already high and you were trying to reduce the temperature by cooling before starting a wipe. This has now been corrected so that the temperature in the drive
|
||||
selection window is updated every 60 seconds. @PartialVolume #407
|
||||
- Fixes a zombie nwipe process running at 100% CPU on one core but only on a Konsole based terminal. This only occurred when the Konsole terminal is exited while nwipe is sitting at the drive selection screen but nwipe did not exit when the konsole terminal was closed. If nwipe is exited normally on completion of a wipe or aborted by using control C then this problem would not be seen. Also occurs during a wipe if the konsole terminal is closed without exiting nwipe first, again only on Konsole based terminals. @PartialVolume #408 #409
|
||||
- Fixes a obscure segfault when --logfile option used with a non writable directory. @PartialVolume #410
|
||||
|
||||
selection window is updated every 60 seconds. @PartialVolume [#407](https://github.com/martijnvanbrummelen/nwipe/pull/407)
|
||||
- Fixes a zombie nwipe process running at 100% CPU on one core but only on a Konsole based terminal. This only occurred when the Konsole terminal is exited while nwipe is sitting at the drive selection screen but nwipe did not exit when the konsole terminal was closed. If nwipe is exited normally on completion of a wipe or aborted by using control C then this problem would not be seen. Also occurs during a wipe if the konsole terminal is closed without exiting nwipe first, again only on Konsole based terminals. @PartialVolume [#408](https://github.com/martijnvanbrummelen/nwipe/pull/408) [#409](https://github.com/martijnvanbrummelen/nwipe/pull/409)
|
||||
- Fixes a obscure segfault when --logfile option used with a non writable directory. @PartialVolume [#410](https://github.com/martijnvanbrummelen/nwipe/pull/410)
|
||||
|
||||
v0.32
|
||||
-----------------------
|
||||
@@ -142,7 +164,6 @@ v0.27
|
||||
- Add the Github build CI service and update Readme with build status labels (Thanks louib)
|
||||
- Miscellaneous smaller fixes
|
||||
|
||||
|
||||
v0.26
|
||||
-----
|
||||
- Add exclude drive option (Thanks PartialVolume)
|
||||
|
||||
20
README.md
20
README.md
@@ -30,16 +30,33 @@ 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).
|
||||
|
||||
nwipe is also included in [ShredOS](https://github.com/PartialVolume/shredos.x86_64) which was developed in particular to showcase nwipe as a fast-to-boot standalone method similar to DBAN. ShredOS always contains the latest nwipe version.
|
||||
|
||||
## Limitations regarding solid state drives
|
||||
In the current form nwipe does not sanitize solid state drives (hereinafter referred to as SSDs)
|
||||
of any form (SAS / Sata / NVME) and / or form factor (2.5" / 3.5" / PCI) fully due to their nature:
|
||||
SSDs, as the transistors contained in the memory modules are subject to wear, contain in most cases
|
||||
additional memory modules installed as failover for broken sectors outside
|
||||
of the host accessible space (frequently referred to as "overprovisioning") and for garbage collection.
|
||||
Some manufacturers reserve access to these areas only to disk's own controller and firmware.
|
||||
It is therefor always advised to use nwipe / shredOS in conjunction with the manufacturer's or hardware vendor's own tools for sanitization to assure
|
||||
full destruction of the information contained on the disk.
|
||||
Given that most vendors and manufacturers do not provide open source tools, it is advised to validate the outcome by comparing the data on the disk before and after sanitization.
|
||||
A list of the most common tools and instructions for SSD wipes can be found in the [SSD Guide](ssd-guide.md).
|
||||
|
||||
## Compiling & Installing
|
||||
|
||||
For a development setup, see the [Hacking section](#hacking) below. For a bootable version of the very latest nwipe master that you can write to an USB flash drive or CD/DVD, see the [Quick and easy bootable version of nwipe master section](#quick--easy-usb-bootable-version-of-nwipe-master-for-x86_64-systems) below.
|
||||
@@ -208,6 +225,7 @@ And in addition checkout the following distros that all include nwipe:
|
||||
|
||||
- [ShredOS](https://github.com/PartialVolume/shredos.x86_64) Always has the latest nwipe release.
|
||||
- [netboot.xyz](https://github.com/netbootxyz/netboot.xyz) Can network-boot ShredOS.
|
||||
- [DiskDump](https://github.com/Awire9966/DiskDump) nwipe on Debian livecd, can wipe eMMC chips.
|
||||
- [partedmagic](https://partedmagic.com)
|
||||
- [SystemRescueCD](https://www.system-rescue.org)
|
||||
- [gparted live](https://sourceforge.net/projects/gparted/files/gparted-live-testing/1.2.0-2/)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
AC_INIT([nwipe],[0.36],[git@brumit.nl])
|
||||
AC_INIT([nwipe],[0.38],[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.
|
||||
|
||||
@@ -1 +1 @@
|
||||
dist_man_MANS = nwipe.1
|
||||
dist_man_MANS = nwipe.8
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH NWIPE "20" "February 2024" "nwipe version 0.36" "User Commands"
|
||||
.TH NWIPE "8" "Jan 2025" "nwipe version 0.38" "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)
|
||||
@@ -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)
|
||||
|
||||
79
src/alfg/add_lagg_fibonacci_prng.c
Normal file
79
src/alfg/add_lagg_fibonacci_prng.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
43
src/alfg/add_lagg_fibonacci_prng.h
Normal file
43
src/alfg/add_lagg_fibonacci_prng.h
Normal 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
|
||||
17
src/conf.c
17
src/conf.c
@@ -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 ) ) )
|
||||
|
||||
@@ -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 ), "XORoshiro256" );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( prng_type, sizeof( prng_type ), "Unknown" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -813,6 +829,7 @@ int nwipe_get_smart_data( nwipe_context_t* c )
|
||||
char smartctl_command[] = "smartctl -a %s";
|
||||
char smartctl_command2[] = "/sbin/smartctl -a %s";
|
||||
char smartctl_command3[] = "/usr/bin/smartctl -a %s";
|
||||
char smartctl_command4[] = "/usr/sbin/smartctl -a %s";
|
||||
char final_cmd_smartctl[sizeof( smartctl_command3 ) + 256];
|
||||
char result[512];
|
||||
char smartctl_labels_to_anonymize[][18] = {
|
||||
@@ -834,7 +851,14 @@ int nwipe_get_smart_data( nwipe_context_t* c )
|
||||
{
|
||||
if( system( "which /usr/bin/smartctl > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "Command not found. Install smartmontools !" );
|
||||
if( system( "which /usr/sbin/smartctl > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "Command not found. Install smartmontools !" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( final_cmd_smartctl, smartctl_command4, c->device_name );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
11
src/device.c
11
src/device.c
@@ -369,7 +369,6 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
|
||||
|
||||
case NWIPE_DEVICE_SAS:
|
||||
strcpy( next_device->device_type_str, " SAS" );
|
||||
check_HPA = 1;
|
||||
break;
|
||||
|
||||
case NWIPE_DEVICE_MMC:
|
||||
@@ -526,6 +525,7 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, i
|
||||
char smartctl_command[] = "smartctl -i %s";
|
||||
char smartctl_command2[] = "/sbin/smartctl -i %s";
|
||||
char smartctl_command3[] = "/usr/bin/smartctl -i %s";
|
||||
char smartctl_command4[] = "/usr/sbin/smartctl -i %s";
|
||||
char device_shortform[50];
|
||||
char result[512];
|
||||
char final_cmd_readlink[sizeof( readlink_command ) + sizeof( device_shortform )];
|
||||
@@ -706,7 +706,14 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, i
|
||||
{
|
||||
if( system( "which /usr/bin/smartctl > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "Command not found. Install smartmontools !" );
|
||||
if( system( "which /usr/sbin/smartctl > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "Command not found. Install smartmontools !" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( final_cmd_smartctl, smartctl_command4, device );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
206
src/gui.c
206
src/gui.c
@@ -63,6 +63,7 @@
|
||||
#include "hpa_dco.h"
|
||||
#include "customers.h"
|
||||
#include "conf.h"
|
||||
#include "unistd.h"
|
||||
|
||||
#define NWIPE_GUI_PANE 8
|
||||
|
||||
@@ -146,6 +147,9 @@ const char* stats_title = " Statistics ";
|
||||
/* Footer labels. */
|
||||
const char* main_window_footer =
|
||||
"S=Start m=Method p=PRNG v=Verify r=Rounds b=Blanking Space=Select c=Config CTRL+C=Quit";
|
||||
const char* shredos_main_window_footer =
|
||||
"S=Start m=Method p=PRNG v=Verify r=Rounds b=Blanking Space=Select f=Font size c=Config CTRL+C=Quit";
|
||||
char** p_main_window_footer;
|
||||
const char* main_window_footer_warning_lower_case_s = " WARNING: To start the wipe press SHIFT+S (uppercase S) ";
|
||||
|
||||
const char* main_window_footer_warning_no_blanking_with_ops2 =
|
||||
@@ -165,10 +169,15 @@ 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";
|
||||
char** p_end_wipe_footer; /* Contains a pointer to either end_wipe_footer or shredos_end_wipe_footer */
|
||||
const char* end_wipe_footer = "B=[Toggle between dark\\blank\\blue screen] Ctrl+C=Quit";
|
||||
const char* shredos_end_wipe_footer = "b=[Toggle dark\\blank\\blue screen] f=Font size Ctrl+C=Quit";
|
||||
const char* rounds_footer = "Left=Erase Esc=Cancel Ctrl+C=Quit";
|
||||
const char* selection_footer_text_entry = "Esc=Cancel Return=Submit Ctrl+C=Quit";
|
||||
|
||||
/* Keeps track of whether font is standard or double size (applicable to ShredOS only) */
|
||||
int toggle_font_flag = 0;
|
||||
|
||||
/* The number of lines available in the terminal */
|
||||
int stdscr_lines;
|
||||
|
||||
@@ -311,6 +320,17 @@ void nwipe_gui_init( void )
|
||||
/* Enable most special keys. */
|
||||
keypad( stdscr, TRUE );
|
||||
|
||||
/* Initialiase pointer to default end_wipe_footer text */
|
||||
if( access( "/usr/bin/shredos_toggle_font_size.sh", F_OK ) == 0 )
|
||||
{
|
||||
p_end_wipe_footer = (char**) &shredos_end_wipe_footer;
|
||||
p_main_window_footer = (char**) &shredos_main_window_footer;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_end_wipe_footer = (char**) &end_wipe_footer;
|
||||
p_main_window_footer = (char**) &main_window_footer;
|
||||
}
|
||||
/* Create the text/background color pairs */
|
||||
nwipe_init_pairs();
|
||||
|
||||
@@ -321,7 +341,7 @@ void nwipe_gui_init( void )
|
||||
nwipe_gui_create_header_window();
|
||||
|
||||
/* Create the footer window and panel */
|
||||
nwipe_gui_create_footer_window( main_window_footer );
|
||||
nwipe_gui_create_footer_window( *p_main_window_footer );
|
||||
|
||||
/* Create the options window and panel */
|
||||
nwipe_gui_create_options_window();
|
||||
@@ -649,6 +669,10 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
/* Control A toggle status -1=indefined, 0=all drives delected, 1=all drives selected */
|
||||
int select_all_toggle_status = -1;
|
||||
|
||||
/* This is a flag used to exit this function once drives are selected and S is pressed 0=do not start wipe, 1=start
|
||||
* wipe */
|
||||
int startwipe = 0;
|
||||
|
||||
/* Get the terminal size */
|
||||
getmaxyx( stdscr, stdscr_lines, stdscr_cols );
|
||||
|
||||
@@ -671,7 +695,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
do
|
||||
{
|
||||
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, main_window_footer );
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, *p_main_window_footer );
|
||||
|
||||
/* There is one slot per line. */
|
||||
getmaxyx( main_window, wlines, wcols );
|
||||
@@ -719,7 +743,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
|
||||
/* If the user selected an option the footer text would have changed.
|
||||
* Here we set it back to the main key help text */
|
||||
nwipe_gui_create_footer_window( main_window_footer );
|
||||
nwipe_gui_create_footer_window( *p_main_window_footer );
|
||||
|
||||
/* Refresh the stats window */
|
||||
wnoutrefresh( stats_window );
|
||||
@@ -1208,7 +1232,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
wattroff( footer_window, COLOR_PAIR( 10 ) );
|
||||
|
||||
/* After the delay return footer text back to key help */
|
||||
nwipe_gui_amend_footer_window( main_window_footer );
|
||||
nwipe_gui_amend_footer_window( *p_main_window_footer );
|
||||
doupdate();
|
||||
|
||||
break;
|
||||
@@ -1224,7 +1248,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
wattroff( footer_window, COLOR_PAIR( 10 ) );
|
||||
|
||||
/* After the delay return footer text back to key help */
|
||||
nwipe_gui_amend_footer_window( main_window_footer );
|
||||
nwipe_gui_amend_footer_window( *p_main_window_footer );
|
||||
doupdate();
|
||||
|
||||
break;
|
||||
@@ -1268,7 +1292,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
wattroff( footer_window, COLOR_PAIR( 10 ) );
|
||||
|
||||
/* After the delay return footer text back to key help */
|
||||
nwipe_gui_amend_footer_window( main_window_footer );
|
||||
nwipe_gui_amend_footer_window( *p_main_window_footer );
|
||||
doupdate();
|
||||
|
||||
/* Remove any repeated S key strokes, without this the gui would hang
|
||||
@@ -1284,6 +1308,10 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
/* Remove the S from keystroke, which allows us to stay within the selection menu loop */
|
||||
keystroke = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
startwipe = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -1300,7 +1328,7 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
wattroff( footer_window, COLOR_PAIR( 10 ) );
|
||||
|
||||
/* After the delay return footer text back to key help */
|
||||
nwipe_gui_amend_footer_window( main_window_footer );
|
||||
nwipe_gui_amend_footer_window( *p_main_window_footer );
|
||||
doupdate();
|
||||
|
||||
/* Remove any repeated s key strokes, without this the gui would hang
|
||||
@@ -1349,6 +1377,19 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
||||
/* The f key is only meaningful for ShredOS, it toggles the fontsize */
|
||||
if( access( "/usr/bin/shredos_toggle_font_size.sh", F_OK ) == 0 )
|
||||
{
|
||||
if( system( "/usr/bin/shredos_toggle_font_size.sh > /dev/null 2>&1" ) == 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_INFO, "Toggle font size" );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
} /* keystroke switch */
|
||||
|
||||
/* Check the terminal size, if the user has changed it the while loop checks for
|
||||
@@ -1369,13 +1410,13 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
|
||||
while( validkeyhit == 0 && terminate_signal != 1 && stdscr_cols_previous == stdscr_cols
|
||||
&& stdscr_lines_previous == stdscr_lines );
|
||||
|
||||
} while( keystroke != 'S' && terminate_signal != 1 );
|
||||
} while( startwipe == 0 && terminate_signal != 1 );
|
||||
|
||||
if( keystroke == 'S' )
|
||||
if( startwipe == 1 )
|
||||
{
|
||||
/* If user has pressed S to start wipe change status line */
|
||||
werase( footer_window );
|
||||
nwipe_gui_title( footer_window, end_wipe_footer );
|
||||
nwipe_gui_title( footer_window, *p_end_wipe_footer );
|
||||
wnoutrefresh( footer_window );
|
||||
}
|
||||
|
||||
@@ -1599,10 +1640,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;
|
||||
@@ -1636,7 +1681,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. */
|
||||
@@ -1651,6 +1703,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. */
|
||||
@@ -1734,7 +1788,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 );
|
||||
@@ -1794,6 +1941,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:
|
||||
@@ -3738,7 +3893,7 @@ void nwipe_gui_list( int count, char* window_title, char** list, int* selected_e
|
||||
do
|
||||
{
|
||||
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, main_window_footer );
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, *p_main_window_footer );
|
||||
|
||||
/* There is one slot per line. */
|
||||
getmaxyx( main_window, wlines, wcols );
|
||||
@@ -6191,7 +6346,7 @@ void* nwipe_gui_status( void* ptr )
|
||||
nwipe_time_start = time( NULL ) - 1;
|
||||
}
|
||||
|
||||
nwipe_gui_title( footer_window, end_wipe_footer );
|
||||
nwipe_gui_title( footer_window, *p_end_wipe_footer );
|
||||
|
||||
loop_control = 1;
|
||||
|
||||
@@ -6264,7 +6419,7 @@ void* nwipe_gui_status( void* ptr )
|
||||
if( nwipe_active != 0 )
|
||||
{
|
||||
/* if resizing the terminal during a wipe a specific footer is required */
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, end_wipe_footer );
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 0, *p_end_wipe_footer );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6302,7 +6457,7 @@ void* nwipe_gui_status( void* ptr )
|
||||
{
|
||||
tft_saver = 0;
|
||||
nwipe_init_pairs();
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 1, end_wipe_footer );
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 1, *p_end_wipe_footer );
|
||||
|
||||
/* Show screen */
|
||||
nwipe_gui_blank = 0;
|
||||
@@ -6319,7 +6474,7 @@ void* nwipe_gui_status( void* ptr )
|
||||
show_panel( main_panel );
|
||||
|
||||
/* Reprint the footer */
|
||||
nwipe_gui_title( footer_window, end_wipe_footer );
|
||||
nwipe_gui_title( footer_window, *p_end_wipe_footer );
|
||||
|
||||
// Refresh the footer_window ;
|
||||
wnoutrefresh( footer_window );
|
||||
@@ -6342,7 +6497,7 @@ void* nwipe_gui_status( void* ptr )
|
||||
/* grey text on black background */
|
||||
tft_saver = 1;
|
||||
nwipe_init_pairs();
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 1, end_wipe_footer );
|
||||
nwipe_gui_create_all_windows_on_terminal_resize( 1, *p_end_wipe_footer );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6410,6 +6565,19 @@ void* nwipe_gui_status( void* ptr )
|
||||
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
||||
/* The f key is only meaningful for ShredOS, it toggles the fontsize */
|
||||
if( access( "/usr/bin/shredos_toggle_font_size.sh", F_OK ) == 0 )
|
||||
{
|
||||
if( system( "/usr/bin/shredos_toggle_font_size.sh > /dev/null 2>&1" ) == 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_INFO, "Toggle font size" );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
@@ -59,13 +59,15 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
int dco_line_found;
|
||||
|
||||
FILE* fp;
|
||||
char path_hdparm_cmd1_get_hpa[] = "hdparm --verbose -N";
|
||||
char path_hdparm_cmd2_get_hpa[] = "/sbin/hdparm --verbose -N";
|
||||
char path_hdparm_cmd3_get_hpa[] = "/usr/bin/hdparm --verbose -N";
|
||||
char path_hdparm_cmd10_get_hpa[] = "hdparm --verbose -N";
|
||||
char path_hdparm_cmd20_get_hpa[] = "/sbin/hdparm --verbose -N";
|
||||
char path_hdparm_cmd30_get_hpa[] = "/usr/bin/hdparm --verbose -N";
|
||||
char path_hdparm_cmd31_get_hpa[] = "/usr/sbin/hdparm --verbose -N";
|
||||
|
||||
char path_hdparm_cmd4_get_dco[] = "hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd5_get_dco[] = "/sbin/hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd6_get_dco[] = "/usr/bin/hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd40_get_dco[] = "hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd50_get_dco[] = "/sbin/hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd60_get_dco[] = "/usr/bin/hdparm --verbose --dco-identify";
|
||||
char path_hdparm_cmd61_get_dco[] = "/usr/sbin/hdparm --verbose --dco-identify";
|
||||
|
||||
char pipe_std_err[] = "2>&1";
|
||||
|
||||
@@ -78,8 +80,8 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
/* Use the longest of the 'path_hdparm_cmd.....' strings above to
|
||||
*determine size in the strings below
|
||||
*/
|
||||
char hdparm_cmd_get_hpa[sizeof( path_hdparm_cmd3_get_hpa ) + sizeof( c->device_name ) + sizeof( pipe_std_err )];
|
||||
char hdparm_cmd_get_dco[sizeof( path_hdparm_cmd6_get_dco ) + sizeof( c->device_name ) + sizeof( pipe_std_err )];
|
||||
char hdparm_cmd_get_hpa[sizeof( path_hdparm_cmd30_get_hpa ) + sizeof( c->device_name ) + sizeof( pipe_std_err )];
|
||||
char hdparm_cmd_get_dco[sizeof( path_hdparm_cmd60_get_dco ) + sizeof( c->device_name ) + sizeof( pipe_std_err )];
|
||||
|
||||
/* Initialise return value */
|
||||
set_return_value = 0;
|
||||
@@ -96,25 +98,43 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
{
|
||||
if( system( "which /usr/bin/hdparm > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "hdparm command not found." );
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"Required by nwipe for HPA/DCO detection & correction and ATA secure erase." );
|
||||
nwipe_log( NWIPE_LOG_WARNING, "** Please install hdparm **\n" );
|
||||
cleanup();
|
||||
exit( 1 );
|
||||
if( system( "which /usr/sbin/hdparm > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "hdparm command not found." );
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"Required by nwipe for HPA/DCO detection & correction and ATA secure erase." );
|
||||
nwipe_log( NWIPE_LOG_WARNING, "** Please install hdparm **\n" );
|
||||
cleanup();
|
||||
exit( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( hdparm_cmd_get_hpa,
|
||||
sizeof( hdparm_cmd_get_hpa ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd31_get_hpa,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
snprintf( hdparm_cmd_get_dco,
|
||||
sizeof( hdparm_cmd_get_dco ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd61_get_dco,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( hdparm_cmd_get_hpa,
|
||||
sizeof( hdparm_cmd_get_hpa ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd3_get_hpa,
|
||||
path_hdparm_cmd30_get_hpa,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
snprintf( hdparm_cmd_get_dco,
|
||||
sizeof( hdparm_cmd_get_dco ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd6_get_dco,
|
||||
path_hdparm_cmd60_get_dco,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
}
|
||||
@@ -124,13 +144,13 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
snprintf( hdparm_cmd_get_hpa,
|
||||
sizeof( hdparm_cmd_get_hpa ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd2_get_hpa,
|
||||
path_hdparm_cmd20_get_hpa,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
snprintf( hdparm_cmd_get_dco,
|
||||
sizeof( hdparm_cmd_get_dco ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd5_get_dco,
|
||||
path_hdparm_cmd50_get_dco,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
}
|
||||
@@ -140,13 +160,13 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
snprintf( hdparm_cmd_get_hpa,
|
||||
sizeof( hdparm_cmd_get_hpa ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd1_get_hpa,
|
||||
path_hdparm_cmd10_get_hpa,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
snprintf( hdparm_cmd_get_dco,
|
||||
sizeof( hdparm_cmd_get_dco ),
|
||||
"%s %s %s\n",
|
||||
path_hdparm_cmd4_get_dco,
|
||||
path_hdparm_cmd40_get_dco,
|
||||
c->device_name,
|
||||
pipe_std_err );
|
||||
}
|
||||
@@ -570,13 +590,22 @@ int hpa_dco_status( nwipe_context_t* ptr )
|
||||
* through */
|
||||
if( c->HPA_reported_set == 0 && c->HPA_reported_real == 0 && c->DCO_reported_real_max_sectors <= 1 )
|
||||
{
|
||||
c->HPA_status = HPA_UNKNOWN;
|
||||
if( c->device_bus == NWIPE_DEVICE_USB )
|
||||
if( c->device_bus == NWIPE_DEVICE_SAS )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"HIDDEN SECTORS INDETERMINATE! on %s, Some USB adapters & memory sticks don't support "
|
||||
"ATA pass through",
|
||||
c->device_name );
|
||||
/* SAS SCSI doesn't appear to support HPA/DCO commands */
|
||||
c->HPA_status = HPA_NOT_APPLICABLE;
|
||||
nwipe_log( NWIPE_LOG_INFO, "No hidden sectors on %s", c->device_name );
|
||||
}
|
||||
else
|
||||
{
|
||||
c->HPA_status = HPA_UNKNOWN;
|
||||
if( c->device_bus == NWIPE_DEVICE_USB )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"HIDDEN SECTORS INDETERMINATE! on %s, Some USB adapters & memory sticks don't support "
|
||||
"ATA pass through",
|
||||
c->device_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -722,6 +751,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"
|
||||
*/
|
||||
|
||||
@@ -629,25 +629,81 @@ void fix_endian_model_names( char* model )
|
||||
int idx2 = 0;
|
||||
unsigned int length = 0;
|
||||
char* tmp_string;
|
||||
char* model_lower_case;
|
||||
int swap_endian_flag = 0;
|
||||
|
||||
length = strlen( model );
|
||||
|
||||
tmp_string = calloc( length, 1 );
|
||||
tmp_string = calloc( length + 1, 1 );
|
||||
model_lower_case = calloc( length + 1, 1 );
|
||||
|
||||
strncpy( model_lower_case, model, length );
|
||||
model_lower_case[length] = 0; /* makesure it's terminated */
|
||||
strlower( model_lower_case ); /* convert to lower case for comparison */
|
||||
|
||||
/* "ASSMNU G" = "SAMSUNG ", tested against model Samsung HM160HC so that
|
||||
* "ASSMNU G MH61H0 C" becomes "SAMSUNG HM160HC ")
|
||||
*/
|
||||
if( !( strncmp( model, "ASSMNU G", 8 ) ) )
|
||||
|
||||
if( !( strncmp( model_lower_case, "assmnu g", 8 ) ) )
|
||||
{
|
||||
while( model[idx] != 0 )
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hitachi */
|
||||
if( !( strncmp( model_lower_case, "ihathc i", 8 ) ) )
|
||||
{
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Toshiba */
|
||||
if( !( strncmp( model_lower_case, "othsbi a", 8 ) ) )
|
||||
{
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* WDC (Western Digital Corporation) */
|
||||
if( !( strncmp( model_lower_case, "dw c", 4 ) ) )
|
||||
{
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Seagate */
|
||||
if( !( strncmp( model_lower_case, "esgata e", 8 ) ) )
|
||||
{
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Seagate models starting ST */
|
||||
if( !( strncmp( model_lower_case, "ts", 2 ) ) )
|
||||
{
|
||||
swap_endian_flag = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( swap_endian_flag == 1 )
|
||||
{
|
||||
while( model[idx] != 0 && idx < length )
|
||||
{
|
||||
tmp_string[idx2 + 1] = model[idx];
|
||||
if( model[idx + 1] != 0 )
|
||||
{
|
||||
/* Swap the bytes */
|
||||
tmp_string[idx2 + 1] = model[idx];
|
||||
tmp_string[idx2] = model[idx + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the last odd byte and exit while loop */
|
||||
tmp_string[idx2] = model[idx];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -660,7 +716,10 @@ void fix_endian_model_names( char* model )
|
||||
idx2 += 2;
|
||||
}
|
||||
|
||||
tmp_string[idx2 + 1] = 0;
|
||||
strcpy( model, tmp_string );
|
||||
tmp_string[length] = 0; /* terminate */
|
||||
strncpy( model, tmp_string, length );
|
||||
model[length] = 0; /* terminate */
|
||||
}
|
||||
free( tmp_string );
|
||||
free( model_lower_case );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
15
src/nwipe.c
15
src/nwipe.c
@@ -171,12 +171,15 @@ int main( int argc, char** argv )
|
||||
{
|
||||
if( system( "which /usr/bin/hdparm > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "hdparm command not found." );
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"Required by nwipe for HPA/DCO detection & correction and ATA secure erase." );
|
||||
nwipe_log( NWIPE_LOG_WARNING, "** Please install hdparm **\n" );
|
||||
cleanup();
|
||||
exit( 1 );
|
||||
if( system( "which /usr/sbin/hdparm > /dev/null 2>&1" ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_WARNING, "hdparm command not found." );
|
||||
nwipe_log( NWIPE_LOG_WARNING,
|
||||
"Required by nwipe for HPA/DCO detection & correction and ATA secure erase." );
|
||||
nwipe_log( NWIPE_LOG_WARNING, "** Please install hdparm **\n" );
|
||||
cleanup();
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -490,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 );
|
||||
@@ -539,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.
|
||||
@@ -592,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" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,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" );
|
||||
@@ -677,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" );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
90
src/prng.c
90
src/prng.c
@@ -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,84 @@ 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, (uint64_t*) ( seed->s ), seed->length / sizeof( uint64_t ) );
|
||||
|
||||
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, (uint64_t*) ( seed->s ), seed->length / sizeof( uint64_t ) );
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
14
src/prng.h
14
src/prng.h
@@ -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_ */
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
* used by configure to dynamically assign those values
|
||||
* to documentation files.
|
||||
*/
|
||||
const char* version_string = "0.36";
|
||||
const char* version_string = "0.38";
|
||||
const char* program_name = "nwipe";
|
||||
const char* author_name = "Martijn van Brummelen";
|
||||
const char* email_address = "git@brumit.nl";
|
||||
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\
|
||||
Andy Beverley <andy@andybev.com> Martijn van Brummelen <martijn@brumit.nl>\n\
|
||||
Nick Law <shredos.eraser@gmail.com> (@PartialVolume) and others\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.36";
|
||||
const char* banner = "nwipe 0.38";
|
||||
|
||||
46
src/xor/README.md
Normal file
46
src/xor/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# XORoshiro-256 PRNG by Fabian Druschke
|
||||
|
||||
## Overview
|
||||
|
||||
This repository contains the implementation of **XORoshiro-256**, a novel pseudorandom number generator (PRNG) developed and implemented by **Fabian Druschke**. This algorithm is based on the widely known XORoshiro-128** family of PRNGs but has been extended to use a 256-bit internal state to deliver higher throughput and randomness quality.
|
||||
|
||||
This implementation is specifically designed for **nwipe**, a secure data wiping tool, and has been optimized to deliver fast and high-quality random data generation on **64-bit systems**. The focus of this PRNG is to provide rapid throughput without compromising on randomness quality for non-cryptographic applications.
|
||||
|
||||
## Key Differences from XORoshiro-128**
|
||||
|
||||
The **XORoshiro-256** implementation retains the core principles of the XORoshiro-128** algorithm but introduces several key modifications to improve its performance and applicability in specific use cases:
|
||||
|
||||
- **Expanded State Size**: Unlike XORoshiro-128**, which uses a 128-bit internal state, **XORoshiro-256** utilizes a 256-bit state. This change increases the entropy potential and allows the generator to handle a larger amount of randomness, making it more resilient to state collisions over longer sequences.
|
||||
|
||||
- **Full State Output**: In XORoshiro-128**, the output is derived by manipulating part of the internal state. In **XORoshiro-256**, the entire 256-bit internal state is written directly into the output buffer after each iteration. This ensures that the full state is leveraged for output, maximizing the randomness per cycle.
|
||||
|
||||
- **Customized Rotation and Shift Operations**: The core operations (XOR, rotate, shift) have been carefully tuned in **XORoshiro-256** to maintain high entropy propagation throughout the internal state. The rotations and shifts are specifically designed to distribute randomness across the full state efficiently.
|
||||
|
||||
- **Optimized for nwipe**: This PRNG has been tailored for **nwipe**, where fast, secure, and high-throughput random number generation is essential for secure data wiping processes. **XORoshiro-256** is optimized to run efficiently on **64-bit systems**, delivering high performance and quality randomness.
|
||||
|
||||
- **Non-cryptographic**: As with XORoshiro-128**, **XORoshiro-256** is not suitable for cryptographic purposes. While it provides high-quality randomness for general applications, it is predictable and lacks the security features needed for cryptographic use.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
The **XORoshiro-256 PRNG** has been developed following **best practices**, with a focus on performance and randomness quality. However, **Fabian Druschke** makes **no warranties** regarding the suitability of this algorithm for specific use cases. This PRNG is **not intended for cryptographic purposes**, and users should exercise caution when using it in sensitive environments.
|
||||
|
||||
By using this software, you agree that **Fabian Druschke** is not responsible for any potential issues, damages, or data loss resulting from its use. The software is provided "as-is" and is used at your own risk.
|
||||
|
||||
## License
|
||||
|
||||
This implementation is released into the **public domain**. You are free to use, modify, and distribute this software for any purpose, without restriction. Please note that there are **no guarantees** of the quality of the randomness generated or its fitness for any particular purpose.
|
||||
|
||||
## Use Case
|
||||
|
||||
This PRNG has been designed to meet the specific needs of **nwipe**, a data wiping tool where fast and secure random data generation is crucial. It is optimized for **64-bit architectures** and ensures a high level of performance when generating large amounts of random data quickly.
|
||||
|
||||
## Mathematical and Statistical Analysis
|
||||
|
||||
The **entropy** and **randomness properties** of the XORoshiro-256 PRNG have been rigorously tested. The algorithm's **entropy propagation** has been proven mathematically, and it has been subjected to a variety of statistical tests, including **Diehard** and **TestU01**, to evaluate its randomness quality.
|
||||
|
||||
For more detailed information on the mathematical proof and statistical analysis, please refer to the [paper](./XOROSHIRO_PROOF_OF_CONCEPT.md).
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions to this project are welcome! If you have suggestions for improvements or want to collaborate, feel free to open an issue or submit a pull request.
|
||||
|
||||
294
src/xor/XOROSHIRO_PROOF_OF_CONCEPT.md
Normal file
294
src/xor/XOROSHIRO_PROOF_OF_CONCEPT.md
Normal file
@@ -0,0 +1,294 @@
|
||||
---
|
||||
title: "Proof of Entropy and Randomness: Implementation and Analysis of a Modified XORoshiro-256 PRNG"
|
||||
author: "Fabian Druschke"
|
||||
date: "2024-03-13"
|
||||
---
|
||||
|
||||
# **Proof of Entropy and Randomness: Analysis of a Modified XORoshiro-256 PRNG**
|
||||
|
||||
**Author**: Fabian Druschke
|
||||
**Date**: March 13, 2024
|
||||
|
||||
---
|
||||
|
||||
## **Abstract**
|
||||
|
||||
This paper provides a detailed analysis of the entropy characteristics of a modified XORoshiro-256-based pseudorandom number generator (PRNG). By increasing the internal state size to 256 bits and outputting the entire state in each iteration, we investigate the entropy propagation through the state transitions. The results demonstrate the viability of this PRNG for non-cryptographic applications with high entropy requirements. The paper further presents a mathematical proof of the entropy levels, supported by empirical tests.
|
||||
|
||||
---
|
||||
|
||||
## **Table of Contents**
|
||||
|
||||
1. Introduction
|
||||
2. Description of the Modified XORoshiro-256 Algorithm
|
||||
3. Mathematical Analysis of Entropy Propagation
|
||||
4. Example: Entropy Propagation for Seed A
|
||||
5. Empirical Testing and Results
|
||||
6. Conclusion
|
||||
7. References
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
# **Mathematical Analysis and Entropy Evaluation of a Modified XORoshiro-128-Based PRNG with Seed A**
|
||||
|
||||
|
||||
## **Abstract**
|
||||
|
||||
This paper presents a thorough mathematical analysis of a custom pseudorandom number generator (PRNG), based on a modification of the XORoshiro-128 algorithm. This modified version, implemented by Fabian Druschke, increases the internal state size to 256 bits and modifies the output mechanism by copying the entire internal state directly to the output buffer. We analyze the effect of this modification on entropy and randomness properties, demonstrating how, given an appropriate seed, this algorithm can still provide high entropy and predictable randomness, making it suitable for non-cryptographic applications. Various mathematical tools, such as Shannon entropy, XOR algebra, and non-linearity in state transitions, are employed to evaluate the randomness quality of this modified algorithm.
|
||||
|
||||
---
|
||||
|
||||
## **1. Introduction**
|
||||
|
||||
### **1.1 Background on Pseudo-Random Number Generators (PRNGs)**
|
||||
|
||||
Pseudo-random number generators (PRNGs) are algorithms that generate sequences of numbers approximating the properties of random numbers. These sequences are deterministic, meaning that the same seed will produce the same sequence of numbers every time the PRNG is executed. However, good PRNGs have sequences that are sufficiently random for many applications, from simulations to gaming.
|
||||
|
||||
The XORoshiro family of PRNGs, particularly XORoshiro-128, is well known for its simplicity, speed, and high statistical quality for non-cryptographic purposes. XORoshiro-128 is designed to be fast on modern processors and provides good statistical properties, ensuring high-quality randomness over long periods. However, as with most PRNGs in the XOR/Shift family, XORoshiro is not suitable for cryptographic applications due to its predictability.
|
||||
|
||||
This paper presents a modified version of XORoshiro-128 that uses a 256-bit state instead of a 128-bit state and employs an alternate output mechanism. Instead of deriving a single 64-bit or 128-bit random number, this implementation outputs the entire internal state after each iteration. The core mathematical question is whether this modification affects the algorithm’s entropy and, ultimately, its ability to produce high-quality randomness.
|
||||
|
||||
### **1.2 Definition of Entropy in PRNGs**
|
||||
|
||||
In PRNGs, entropy refers to the unpredictability of the generated sequence. Ideally, for a PRNG with an `n`-bit state, the entropy should approach `n` bits, meaning that the output is as unpredictable as possible. The mathematical concept of entropy can be understood through Shannon entropy, defined as:
|
||||
|
||||
```
|
||||
H(X) = - Σ P(x_i) log2(P(x_i))
|
||||
```
|
||||
|
||||
Where `P(x_i)` is the probability of occurrence of the state `x_i`. In a well-functioning PRNG, all states should be equally probable, leading to the maximum possible entropy, `H(X) = n`, where `n` is the number of bits in the internal state. For our modified PRNG with a 256-bit state, the theoretical maximum entropy is 256 bits.
|
||||
|
||||
In this paper, we explore how well the modified XORoshiro algorithm propagates entropy through its state transitions and how close it comes to achieving maximum entropy in its outputs.
|
||||
|
||||
---
|
||||
|
||||
## **2. Description of the Modified XORoshiro-128 Algorithm**
|
||||
|
||||
### **2.1 Algorithm Overview**
|
||||
|
||||
The original XORoshiro-128 algorithm uses two 64-bit integers to form a 128-bit internal state. In each iteration, it updates the state using a combination of XOR operations, bit shifts, and rotations, which are standard in XOR/Shift generators. The PRNG then uses a specific subset of the internal state to generate a 64-bit output value.
|
||||
|
||||
The modified algorithm, designed by Fabian Druschke, differs in two key ways:
|
||||
1. **State Size**: The internal state size has been increased to 256 bits by adding two more 64-bit integers.
|
||||
2. **Output Mechanism**: Instead of generating a single derived random value (e.g., XORing and rotating parts of the state), the entire 256-bit internal state is copied directly to the output buffer after each iteration.
|
||||
|
||||
### **2.2 State Transition Function**
|
||||
|
||||
At the heart of the PRNG is the state transition function, which updates the internal state on each iteration. The following operations are performed on the internal state variables `s[0], s[1], s[2], s[3]`:
|
||||
|
||||
```c
|
||||
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);
|
||||
```
|
||||
|
||||
Here’s a breakdown of the key operations:
|
||||
1. **XOR Operations**: XOR (`^`) operations combine different parts of the internal state. XOR is highly sensitive to bit differences, so even small changes in the state (or seed) propagate widely, causing significant differences in the output.
|
||||
2. **Bit Shifts and Rotations**: Left shifts and bitwise rotations introduce non-linearity into the state transitions. Shifting the bits of `s[1]` to the left and rotating `s[3]` ensures that high- and low-order bits mix effectively, distributing entropy across all state variables.
|
||||
|
||||
### **2.3 Output Mechanism**
|
||||
|
||||
In the original XORoshiro-128 algorithm, the output is typically a derived value from the state, such as the result of rotating and multiplying specific state variables. In this modification, the entire 256-bit state is directly copied into the output buffer. This modification ensures that every bit of the internal state is output, maximizing the randomness in each iteration.
|
||||
|
||||
```c
|
||||
memcpy(bufpos, state->s, 32); // Outputs the entire state (256 bits)
|
||||
```
|
||||
|
||||
This approach differs from most PRNGs that only output a portion of their internal state, as it leverages the full state for every output. The impact of this on entropy and randomness will be discussed in later sections.
|
||||
|
||||
---
|
||||
|
||||
## **3. Mathematical Analysis of Entropy Propagation**
|
||||
|
||||
### **3.1 State Transition and Bitwise Operations**
|
||||
|
||||
The core challenge of any PRNG is to propagate entropy through its state so that future outputs are unpredictable based on past outputs. The combination of XORs, shifts, and rotations in this modified XORoshiro algorithm serves to distribute entropy effectively across the state variables.
|
||||
|
||||
#### **XOR’s Role in Entropy Propagation**
|
||||
|
||||
The XOR operation is central to the success of this PRNG, as it is both non-linear and highly sensitive to input changes. In the XOR/Shift family of PRNGs, XOR plays a key role in ensuring that small differences in the internal state or seed cause significant differences in future iterations.
|
||||
|
||||
Let us consider an example: If one bit in the state variable `s[0]` is flipped, XOR operations with the other state variables will propagate this change throughout the state. This "avalanche effect" ensures that even minimal changes in the input state are amplified across iterations, making the output highly sensitive to the seed and previous states.
|
||||
|
||||
Mathematically, for any two bits `a` and `b`:
|
||||
|
||||
```
|
||||
a ^ b = 1 if a != b
|
||||
a ^ b = 0 if a == b
|
||||
```
|
||||
|
||||
This means that the XOR operation will generate new bits that are difficult to predict from the original values of `a` and `b`, as it effectively adds the differences between these bits. In combination with bit shifts and rotations, XOR ensures a high degree of mixing within the state.
|
||||
|
||||
#### **Bit Shifts and Rotations**
|
||||
|
||||
Bit shifts and rotations introduce additional complexity into the state transitions. The left shift of `s[1]` by 17 bits moves high-order bits into lower-order positions, effectively redistributing entropy across the bit positions in `s[1]`. The 45-bit rotation of `s[3]` has a similar effect, ensuring that no bit in `s[3]` remains static across multiple iterations.
|
||||
|
||||
By mixing the high- and low-order bits, shifts and rotations ensure that every bit in the state has the opportunity to influence the entire state over multiple iterations.
|
||||
|
||||
### **3.2 Period Length and Entropy Retention**
|
||||
|
||||
A critical aspect of any PRNG is its period—the length of the sequence before the internal state repeats. For a PRNG with a 256-bit state, the maximum possible period is `2^256 - 1`. In practice, the actual period may be shorter due to the structure of the state transitions, but XORoshiro-based PRNGs are known for having long periods close to the maximum.
|
||||
|
||||
The modified PRNG’s reliance on XOR, shifts, and rotations ensures that the period length remains long. Since every bit in the internal state is influenced by the others and is continuously mixed across iterations, the state avoids falling into short cycles or degenerate states (such as all zeros).
|
||||
|
||||
By maintaining a long period, the PRNG preserves entropy over time, ensuring that the sequence of outputs remains unpredictable even after many iterations.
|
||||
|
||||
---
|
||||
|
||||
## **4. Example: Entropy Propagation for Seed A**
|
||||
|
||||
To illustrate how entropy propagates through the modified PRNG, let us consider an example where the seed `A` is:
|
||||
|
||||
```
|
||||
A = { 0x123456789ABCDEF0, 0x0FEDCBA987654321, 0x1111111111111111,
|
||||
|
||||
0x2222222222222222 }
|
||||
```
|
||||
|
||||
The internal state is initialized as:
|
||||
|
||||
```
|
||||
s[0] = 0x123456789ABCDEF0
|
||||
s[1] = 0x0FEDCBA987654321
|
||||
s[2] = 0x1111111111111111
|
||||
s[3] = 0x2222222222222222
|
||||
```
|
||||
|
||||
After the first iteration, the XOR and rotation operations produce the following results:
|
||||
|
||||
1. **Bit Shift**:
|
||||
```
|
||||
t = 0x0FEDCBA987654321 << 17 = 0x1FDB97530ECA8642
|
||||
```
|
||||
|
||||
2. **XOR and Rotations**:
|
||||
```
|
||||
s[2] = s[2] ^ s[0] = 0x1111111111111111 ^ 0x123456789ABCDEF0 = 0x03256768A9BCDEF1
|
||||
```
|
||||
```
|
||||
s[3] = s[3] ^ s[1] = 0x2222222222222222 ^ 0x0FEDCBA987654321 = 0x2EEDAB8B75576603
|
||||
```
|
||||
```
|
||||
s[1] = s[1] ^ s[2] = 0x0FEDCBA987654321 ^ 0x03256768A9BCDEF1 = 0x0CFBBA987E785EF0
|
||||
```
|
||||
```
|
||||
s[0] = s[0] ^ s[3] = 0x123456789ABCDEF0 ^ 0x2EEDAB8B75576603 = 0x3CDFED032DF9B9F3
|
||||
```
|
||||
```
|
||||
s[2] = s[2] ^ t = 0x03256768A9BCDEF1 ^ 0x1FDB97530ECA8642 = 0x1CF80E4B177342D3
|
||||
```
|
||||
```
|
||||
s[3] = rotl(0x2EEDAB8B75576603, 45) = 0xABF4A5E51B76F3C9
|
||||
```
|
||||
|
||||
Even after one iteration, it is clear that the original seed has been thoroughly mixed into the state variables. Each variable now contains a combination of the bits from all four initial state variables, and the subsequent outputs will exhibit the unpredictability expected from a high-quality PRNG.
|
||||
|
||||
---
|
||||
|
||||
## **5. Entropy Evaluation**
|
||||
|
||||
### **5.1 Shannon Entropy**
|
||||
|
||||
Shannon entropy is a key measure of the randomness of a PRNG. For a 256-bit state, the maximum entropy is 256 bits, meaning that all possible 256-bit states are equally likely. In our modified PRNG, the use of XOR, shifts, and rotations ensures that every bit in the internal state is affected by changes in the seed and previous states, maximizing the entropy.
|
||||
|
||||
Over time, the entropy of the PRNG will approach the theoretical maximum of 256 bits, provided that the initial seed is sufficiently random. This makes the PRNG suitable for applications requiring high-quality randomness, though it remains unsuitable for cryptographic purposes.
|
||||
|
||||
### **5.2 Kolmogorov Complexity**
|
||||
|
||||
Kolmogorov complexity is a measure of the compressibility of a sequence. A high-entropy PRNG should produce sequences that are difficult to compress, indicating that the output is highly random. Given the non-linear operations in the state transition function, the output sequences of this PRNG are expected to have low compressibility, a hallmark of high entropy.
|
||||
|
||||
### **5.3 Empirical Testing**
|
||||
|
||||
While mathematical analysis provides strong evidence of high entropy, empirical testing using tools like **Diehard** or **TestU01** is necessary to confirm the PRNG’s statistical properties. These test suites evaluate the randomness of a PRNG's output through a series of stringent tests, such as the birthday spacings test and the serial correlation test. Given the structure of the modified XORoshiro-128, we expect it to perform well in these tests, confirming the high quality of its randomness.
|
||||
|
||||
The algorithm has to be proven to be NIST 800-22 compliant.
|
||||
|
||||
|
||||
```
|
||||
A total of 188 tests (some of the 15 tests actually consist of multiple sub-tests)
|
||||
were conducted to evaluate the randomness of 32 bitstreams of 1048576 bits from:
|
||||
|
||||
/dev/loop0
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
The numerous empirical results of these tests were then interpreted with
|
||||
an examination of the proportion of sequences that pass a statistical test
|
||||
(proportion analysis) and the distribution of p-values to check for uniformity
|
||||
(uniformity analysis). The results were the following:
|
||||
|
||||
186/188 tests passed successfully both the analyses.
|
||||
2/188 tests did not pass successfully both the analyses.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
Here are the results of the single tests:
|
||||
|
||||
- The "Frequency" test passed both the analyses.
|
||||
|
||||
- The "Block Frequency" test passed both the analyses.
|
||||
|
||||
- The "Cumulative Sums" (forward) test passed both the analyses.
|
||||
The "Cumulative Sums" (backward) test passed both the analyses.
|
||||
|
||||
- The "Runs" test passed both the analyses.
|
||||
|
||||
- The "Longest Run of Ones" test passed both the analyses.
|
||||
|
||||
- The "Binary Matrix Rank" test FAILED both the analyses.
|
||||
|
||||
- The "Discrete Fourier Transform" test passed both the analyses.
|
||||
|
||||
- 147/148 of the "Non-overlapping Template Matching" tests passed both the analyses.
|
||||
1/148 of the "Non-overlapping Template Matching" tests FAILED the proportion analysis.
|
||||
|
||||
- The "Overlapping Template Matching" test passed both the analyses.
|
||||
|
||||
- The "Maurer's Universal Statistical" test passed both the analyses.
|
||||
|
||||
- The "Approximate Entropy" test passed both the analyses.
|
||||
|
||||
- 8/8 of the "Random Excursions" tests passed both the analyses.
|
||||
|
||||
- 18/18 of the "Random Excursions Variant" tests passed both the analyses.
|
||||
|
||||
- The "Serial" (first) test passed both the analyses.
|
||||
The "Serial" (second) test passed both the analyses.
|
||||
|
||||
- The "Linear Complexity" test passed both the analyses.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
The missing tests (if any) were whether disabled manually by the user or disabled
|
||||
at run time due to input size requirements not satisfied by this run.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## **6. Conclusion**
|
||||
|
||||
In this paper, we have mathematically analyzed the modified XORoshiro-128-based PRNG, implemented by Fabian Druschke. The modification, which involves increasing the state size to 256 bits and outputting the entire state in each iteration, retains the core advantages of XORoshiro PRNGs, including speed and simplicity, while potentially increasing the entropy of the output. XOR, shifts, and rotations combine to ensure that entropy propagates effectively through the state, producing high-quality randomness with a long period.
|
||||
|
||||
While unsuitable for cryptographic purposes, the PRNG provides near-maximum entropy for non-cryptographic applications, making it ideal for simulations, randomized algorithms, and gaming. Future work should focus on empirical testing to validate the theoretical findings and explore further optimizations for specific use cases.
|
||||
|
||||
---
|
||||
|
||||
## **References**
|
||||
|
||||
1. Marsaglia, G. (1996). "DIEHARD: A Battery of Tests of Randomness."
|
||||
2. L’Ecuyer, P., & Simard, R. (2007). "TestU01: A C Library for Empirical Testing of Random Number Generators."
|
||||
3. Blackman, D., & Vigna, S. (2019). "Scrambled Linear Pseudorandom Number Generators."
|
||||
4. Knuth, D. E. (1997). *The Art of Computer Programming, Volume 2: Seminumerical Algorithms*. Addison-Wesley.
|
||||
5. Vigna, S. (2016). "An experimental exploration of Marsaglia's xorshift generators, scrambled."
|
||||
6. National Institute of Standards and Technology (USA) (2011). "A Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications."
|
||||
|
||||
|
||||
74
src/xor/xoroshiro256_prng.c
Normal file
74
src/xor/xoroshiro256_prng.c
Normal 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'
|
||||
}
|
||||
44
src/xor/xoroshiro256_prng.h
Normal file
44
src/xor/xoroshiro256_prng.h
Normal 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
|
||||
51
ssd-guide.md
Normal file
51
ssd-guide.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Guide for the cancellation of solid state media (Sata / SAS / NVME)
|
||||
|
||||
# Index
|
||||
1. Disclaimer & Warning
|
||||
2. Current Standard Commands for Sanitization
|
||||
3. Manufacturer and Vendor Support for Sanitization
|
||||
4. Advised Procedure for Sanitization of SSD-Drives
|
||||
|
||||
# Disclaimer & Warning
|
||||
The following information is given without any warranty and indicates best practices as of the writing of this content.
|
||||
All information should be validated for the precise manufacturer / vendor SKU you want to sanitize.
|
||||
Any sanitization process should be validated by comparing the information contained on the disk before and after sanitization assuring that the previously stored data has been destroyed.
|
||||
Given that most of the manufacturer tools (excluding nvme-cli as it was open sourced from the beginning) available today are closed source, it is not possible to determine with security if the respective tool does or does not effectively verify the outcome of a sanitization.
|
||||
To assure a successful sanitization it is highly recommended to compare the data contained on the disk before and after sanitization and use the manufacturer tool together with tools such as nwipe.
|
||||
|
||||
# Current Standard Commands for Sanitization & Support by Manufacturers and Vendors
|
||||
|
||||
## Current Standards
|
||||
All major block device interface standards contain optional block commands for sanitization.
|
||||
Below are the standards listed for reference:
|
||||
* [SATA ATA/ATAPI Sanitization Command according to ACS-3 Standard](https://people.freebsd.org/~imp/asiabsdcon2015/works/d2161r5-ATAATAPI_Command_Set_-_3.pdf);
|
||||
* [SAS Sanitization Command according to SBC-4 Standard](https://www.t10.org/members/w_sbc4.htm);
|
||||
* [NVME Sanitization Command according to NVME Command Set Specification](https://nvmexpress.org/wp-content/uploads/NVM-Express-NVM-Command-Set-Specification-Revision-1.1-2024.08.05-Ratified.pdf).
|
||||
|
||||
## Manufacturer and Vendor Support for Sanitization
|
||||
Given that the support for sanitization is optional and not a mandatory aspect of the respective standards the support accross vendors can vary largely.
|
||||
The following table does not claim or warrant to be complete, it is highly advised to always validate the information with the manufacturer:
|
||||
|
||||
| Manufacturer | Manufacturer Tool (MFT) | SATA | SAS | NVME |
|
||||
|----------------- |------------------------------------------------------ |----------------- |------------------- |---------- |
|
||||
| Samsung | Samsung DC Toolkit 3.0 | Use MFT* | Use MFT | Use MFT |
|
||||
| Intel / Solidigm | Solidigm™ Storage Tool | Use MFT*\* | Use MFT | Use MFT |
|
||||
| Western Digital | supports SAS / SCSI format unit command | hdparm sanitize | sg_utils sanitize | nvme-cli sanitize |
|
||||
| Sandisk | supports SAS / SATA / SCSI format unit command | hdparm sanitize | sg_utils sanitize | nvme-cli sanitize |
|
||||
| Seagate | Open Seachest | Use MFT | Use MFT | Use MFT |
|
||||
| SK Hynix | Unconfirmed for Linux | N/A | N/A | N/A |
|
||||
| Kioxia | Unconfirmed for Linux | N/A | N/A | N/A |
|
||||
| Micron | Unconfirmed for Linux | N/A | N/A | N/A |
|
||||
| Kingston | Unconfirmed for Linux | N/A | N/A | N/A |
|
||||
| Others | Unconfirmed for Linux | N/A | N/A | N/A |
|
||||
|
||||
\* [DC Toolkit 3.0 contains hdparm, but Interface Standard Compliance is unconfirmed](https://download.semiconductor.samsung.com/resources/user-manual/Samsung_DCToolkit_V3.0_User_Guide.pdf)
|
||||
|
||||
\*\* [Generally Supported, but individual models might offer different levels of support](https://community.solidigm.com/t5/solid-state-drives-nand/support-for-sata-sanitize-command/td-p/24452)
|
||||
|
||||
## Advised Procedure for Sanitization of SSD Drives
|
||||
|
||||
1. Complete an intial sanitization using the manufacturer tools or if supported by the manufacturer use hdparm, sg_utils or nvme;
|
||||
2. Follow up with SHREDOS/Nwipe with a single PRNG stream with verification (PRNG data is extremely hard if not impossible to compress and therefor has to be written out by the firmware);
|
||||
3. Complete an additional sanitization using the manufacturer tools or if supported by the manufacturer use hdparm, sg_utils or nvme;
|
||||
4. Validate that the data has been overwritten.
|
||||
Reference in New Issue
Block a user