From e4ecd6a68eb120657fe7f6513fe80354b0dbe286 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 23 Feb 2023 20:46:19 +0000 Subject: [PATCH 1/5] HPA_DCO_1 - Add HPA, DCO capability 1. Initial commit --- src/Makefile.am | 2 +- src/context.h | 4 ++ src/device.c | 19 +++++- src/hpa_dco.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hpa_dco.h | 33 ++++++++++ src/nwipe.c | 24 +++++++- 6 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 src/hpa_dco.c create mode 100644 src/hpa_dco.h diff --git a/src/Makefile.am b/src/Makefile.am index fe5f9c4..2bd41aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,5 +6,5 @@ AM_LDFLAGS = # this lists the binaries to produce, the (non-PHONY, binary) targets in # the previous manual Makefile bin_PROGRAMS = nwipe -nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h +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 nwipe_LDADD = $(PARTED_LIBS) diff --git a/src/context.h b/src/context.h index 4a00ae8..3a4d6e2 100644 --- a/src/context.h +++ b/src/context.h @@ -157,6 +157,10 @@ typedef struct nwipe_context_t_ time_t end_time; // End time of wipe u64 fsyncdata_errors; // The number of fsyncdata errors across all passes. char PDF_filename[256]; // The filename of the PDF certificate/report. + int HPA_pre_erase_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked + int HPA_post_erase_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked + int DCO_pre_erase_status; // 0 = No DCO found, 1 = DCO detected, 2 = Unknown, unable to checked + int DCO_post_erase_status; // 0 = No DCO found, 1 = DCO detected, 2 = Unknown, unable to checked /* * Identity contains the raw serial number of the drive * (where applicable), however, for use within nwipe use the diff --git a/src/device.c b/src/device.c index 3e8b83b..f984956 100644 --- a/src/device.c +++ b/src/device.c @@ -40,6 +40,7 @@ #include #include #include +#include "hpa_dco.h" #include #include @@ -136,6 +137,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount ) int r; char tmp_serial[21]; nwipe_device_t bus; + int check_HPA; // a flag that indicates whether we check for a HPA on this device bus = 0; @@ -285,19 +287,26 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount ) } } - /* All device strings should be 4 characters, prefix with space if under 4 characters */ + /* All device strings should be 4 characters, prefix with space if under 4 characters + * We also set a switch for certain devices to check for the host protected area (HPA) + */ + check_HPA = 0; + switch( next_device->device_type ) { case NWIPE_DEVICE_UNKNOWN: strcpy( next_device->device_type_str, " UNK" ); + check_HPA = 1; break; case NWIPE_DEVICE_IDE: strcpy( next_device->device_type_str, " IDE" ); + check_HPA = 1; break; case NWIPE_DEVICE_SCSI: strcpy( next_device->device_type_str, " SCSI" ); + check_HPA = 1; break; case NWIPE_DEVICE_COMPAQ: @@ -306,6 +315,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount ) case NWIPE_DEVICE_USB: strcpy( next_device->device_type_str, " USB" ); + check_HPA = 1; break; case NWIPE_DEVICE_IEEE1394: @@ -314,6 +324,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount ) case NWIPE_DEVICE_ATA: strcpy( next_device->device_type_str, " ATA" ); + check_HPA = 1; break; case NWIPE_DEVICE_NVME: @@ -326,9 +337,15 @@ 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; } + if( check_HPA == 1 ) + { + hpa_dco_status( next_device, PRE_WIPE_HPA_CHECK ); + } + if( strlen( (const char*) next_device->device_serial_no ) ) { snprintf( next_device->device_label, diff --git a/src/hpa_dco.c b/src/hpa_dco.c new file mode 100644 index 0000000..e9f4761 --- /dev/null +++ b/src/hpa_dco.c @@ -0,0 +1,159 @@ +/* + * hpa_dco.c: functions that handle the host protected area (HPA) and + * device configuration overlay (DCO) + * + * Copyright PartialVolume . + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#include +#include +#include +#include +#include +#include "nwipe.h" +#include "context.h" +#include "version.h" +#include "method.h" +#include "logging.h" +#include "options.h" +#include "hpa_dco.h" + +int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) +{ + nwipe_context_t* c; + c = ptr; + + int r; // A result buffer. + int set_return_value; + int exit_status; + + FILE* fp; + char hdparm_command[] = "hdparm -N %s"; + char hdparm_command2[] = "/sbin/hdparm -N %s"; + char hdparm_command3[] = "/usr/bin/hdparm -N %s"; + char result[512]; + char device_shortform[50]; + char final_cmd_hdparm[sizeof( hdparm_command ) + sizeof( device_shortform )]; + + /* Initialise return value */ + set_return_value = 0; + + if( system( "which hdparm > /dev/null 2>&1" ) ) + { + if( system( "which /sbin/hdparm > /dev/null 2>&1" ) ) + { + 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 ); + } + else + { + sprintf( final_cmd_hdparm, hdparm_command3, device_shortform ); + } + } + else + { + sprintf( final_cmd_hdparm, hdparm_command2, device_shortform ); + } + } + else + { + sprintf( final_cmd_hdparm, hdparm_command, device_shortform ); + } + + if( final_cmd_hdparm[0] != 0 ) + { + + fp = popen( final_cmd_hdparm, "r" ); + + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_WARNING, "hpa_dco_status: Failed to create stream to %s", hdparm_command ); + + set_return_value = 1; + } + + if( fp != NULL ) + { + /* Read the output a line at a time - output it. */ + if( fgets( result, sizeof( result ) - 1, fp ) != NULL ) + { + if( nwipe_options.verbose ) + { + nwipe_log( NWIPE_LOG_DEBUG, "hdparm -N: %s\n%s", c->device_name, result ); + } + + /* Scan the hdparm results for HPA is disabled + */ + if( pre_or_post == PRE_WIPE_HPA_CHECK ) + { + if( strstr( result, "HPA is disabled" ) != 0 ) + { + c->HPA_pre_erase_status = HPA_DISABLED; + nwipe_log( NWIPE_LOG_INFO, "[GOOD]The host protected area is disabled on %s", c->device_name ); + } + else + { + if( strstr( result, "HPA is enabled" ) != 0 ) + { + c->HPA_pre_erase_status = HPA_ENABLED; + nwipe_log( + NWIPE_LOG_WARNING, "[BAD]The host protected area is enabled on %s", c->device_name ); + } + else + { + c->HPA_pre_erase_status = HPA_UNKNOWN; + } + } + } + } + /* close */ + r = pclose( fp ); + if( r > 0 ) + { + exit_status = WEXITSTATUS( r ); + if( nwipe_options.verbose ) + { + nwipe_log( NWIPE_LOG_WARNING, + "hpa_dco_status(): hdparm failed, \"%s\" exit status = %u", + final_cmd_hdparm, + exit_status ); + } + + if( exit_status == 127 ) + { + nwipe_log( NWIPE_LOG_WARNING, "Command not found. Installing hdparm is mandatory !" ); + set_return_value = 2; + if( nwipe_options.nousb ) + { + return set_return_value; + } + } + } + } + } + return set_return_value; +} diff --git a/src/hpa_dco.h b/src/hpa_dco.h new file mode 100644 index 0000000..1ef7633 --- /dev/null +++ b/src/hpa_dco.h @@ -0,0 +1,33 @@ +/*. + * hpa_dco.h: The header file for the host protected area (HPA) and + * disk configuration overlay routines + * + * Copyright https://github.com/PartialVolume/shredos.x86_64 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef HPA_DCO_H_ +#define HPA_DCO_H_ + +#define HPA_DISABLED 0 +#define HPA_ENABLED 1 +#define HPA_UNKNOWN 2 + +#define PRE_WIPE_HPA_CHECK 0 +#define POST_WIPE_HPA_CHECK 1 + +int hpa_dco_status( nwipe_context_t*, int ); + +#endif /* HPA_DCO_H_ */ diff --git a/src/nwipe.c b/src/nwipe.c index a953be0..c59e016 100644 --- a/src/nwipe.c +++ b/src/nwipe.c @@ -85,6 +85,26 @@ int main( int argc, char** argv ) /* Log nwipes version */ nwipe_log( NWIPE_LOG_INFO, "%s", banner ); + /* Check that hdparm exists, we use hdparm for HPA/DCO detection etc, if not exit nwipe + * required if the PATH environment is not setup ! (Debian sid 'su' as + * opposed to 'su -' + */ + if( system( "which hdparm > /dev/null 2>&1" ) ) + { + if( system( "which /sbin/hdparm > /dev/null 2>&1" ) ) + { + 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 ); + } + } + } + /* Log OS info */ nwipe_log_OSinfo(); @@ -939,8 +959,8 @@ void* signal_hand( void* ptr ) int cleanup() { int i; - extern int log_elements_displayed; - extern int log_elements_allocated; + extern int log_elements_displayed; // initialised and found in logging.c + extern int log_elements_allocated; // initialised and found in logging.c extern char** log_lines; /* Print the logs held in memory. */ From a2d6735b89e4b2b302a31a429ae1f1048fdcaef4 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 23 Feb 2023 21:14:48 +0000 Subject: [PATCH 2/5] HPA_DCO_1 - Add HPA, DCO capability 1. Corrections to hdparm command. --- src/hpa_dco.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hpa_dco.c b/src/hpa_dco.c index e9f4761..aa84e9a 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -50,8 +50,7 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) char hdparm_command2[] = "/sbin/hdparm -N %s"; char hdparm_command3[] = "/usr/bin/hdparm -N %s"; char result[512]; - char device_shortform[50]; - char final_cmd_hdparm[sizeof( hdparm_command ) + sizeof( device_shortform )]; + char final_cmd_hdparm[sizeof( hdparm_command3 ) + sizeof( c->device_name )]; /* Initialise return value */ set_return_value = 0; @@ -71,17 +70,17 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) } else { - sprintf( final_cmd_hdparm, hdparm_command3, device_shortform ); + snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command3, c->device_name ); } } else { - sprintf( final_cmd_hdparm, hdparm_command2, device_shortform ); + snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command2, c->device_name ); } } else { - sprintf( final_cmd_hdparm, hdparm_command, device_shortform ); + snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command, c->device_name ); } if( final_cmd_hdparm[0] != 0 ) From 2747ab5d4f6a143829e8a0005c12ec93df466fbd Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 23 Feb 2023 21:22:21 +0000 Subject: [PATCH 3/5] HPA_DCO_1 - Add HPA, DCO capability 1. More corrections to hdparm command --- src/hpa_dco.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hpa_dco.c b/src/hpa_dco.c index aa84e9a..98bdd91 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -46,9 +46,9 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) int exit_status; FILE* fp; - char hdparm_command[] = "hdparm -N %s"; - char hdparm_command2[] = "/sbin/hdparm -N %s"; - char hdparm_command3[] = "/usr/bin/hdparm -N %s"; + char hdparm_command[] = "hdparm -N"; + char hdparm_command2[] = "/sbin/hdparm -N"; + char hdparm_command3[] = "/usr/bin/hdparm -N"; char result[512]; char final_cmd_hdparm[sizeof( hdparm_command3 ) + sizeof( c->device_name )]; From 09af2bc5a6980bfccf0127ff24495cca62687297 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 23 Feb 2023 21:44:08 +0000 Subject: [PATCH 4/5] HPA_DCO_1 - Add HPA, DCO capability 1. More debugging. --- src/hpa_dco.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hpa_dco.c b/src/hpa_dco.c index 98bdd91..4121216 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -83,6 +83,8 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command, c->device_name ); } + nwipe_log( NWIPE_LOG_DEBUG, "hpa_dco_status: hdparm command %s", final_cmd_hdparm ); + if( final_cmd_hdparm[0] != 0 ) { @@ -90,7 +92,7 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) if( fp == NULL ) { - nwipe_log( NWIPE_LOG_WARNING, "hpa_dco_status: Failed to create stream to %s", hdparm_command ); + nwipe_log( NWIPE_LOG_WARNING, "hpa_dco_status: Failed to create stream to %s", final_cmd_hdparm ); set_return_value = 1; } From ef84c658465a03caa5c31ec92cee488b7147e742 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Thu, 23 Feb 2023 22:30:18 +0000 Subject: [PATCH 5/5] HPA_DCO_1 - Add HPA, DCO capability 1. debugging. --- src/hpa_dco.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hpa_dco.c b/src/hpa_dco.c index 4121216..5d23148 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -70,7 +70,7 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) } else { - snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command3, c->device_name ); + snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s\n", hdparm_command3, c->device_name ); } } else @@ -100,11 +100,11 @@ int hpa_dco_status( nwipe_context_t* ptr, int pre_or_post ) if( fp != NULL ) { /* Read the output a line at a time - output it. */ - if( fgets( result, sizeof( result ) - 1, fp ) != NULL ) + while( fgets( result, sizeof( result ) - 1, fp ) != NULL ) { if( nwipe_options.verbose ) { - nwipe_log( NWIPE_LOG_DEBUG, "hdparm -N: %s\n%s", c->device_name, result ); + nwipe_log( NWIPE_LOG_DEBUG, "%s \n%s", final_cmd_hdparm, result ); } /* Scan the hdparm results for HPA is disabled