Merge pull request #440 from PartialVolume/HPA_DCO

HPA_DCO_1 - Add HPA, DCO capability
This commit is contained in:
PartialVolume
2023-02-23 22:52:38 +00:00
committed by GitHub
6 changed files with 238 additions and 4 deletions

View File

@@ -6,5 +6,5 @@ AM_LDFLAGS =
# this lists the binaries to produce, the (non-PHONY, binary) targets in
# the previous manual Makefile
bin_PROGRAMS = nwipe
nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h
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)

View File

@@ -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

View File

@@ -40,6 +40,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include "hpa_dco.h"
#include <parted/parted.h>
#include <parted/debug.h>
@@ -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,

160
src/hpa_dco.c Normal file
View File

@@ -0,0 +1,160 @@
/*
* hpa_dco.c: functions that handle the host protected area (HPA) and
* device configuration overlay (DCO)
*
* Copyright PartialVolume <https://github.com/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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#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";
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 )];
/* 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
{
snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s\n", hdparm_command3, c->device_name );
}
}
else
{
snprintf( final_cmd_hdparm, sizeof( final_cmd_hdparm ), "%s %s", hdparm_command2, c->device_name );
}
}
else
{
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 )
{
fp = popen( final_cmd_hdparm, "r" );
if( fp == NULL )
{
nwipe_log( NWIPE_LOG_WARNING, "hpa_dco_status: Failed to create stream to %s", final_cmd_hdparm );
set_return_value = 1;
}
if( fp != NULL )
{
/* Read the output a line at a time - output it. */
while( fgets( result, sizeof( result ) - 1, fp ) != NULL )
{
if( nwipe_options.verbose )
{
nwipe_log( NWIPE_LOG_DEBUG, "%s \n%s", final_cmd_hdparm, 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;
}

33
src/hpa_dco.h Normal file
View File

@@ -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_ */

View File

@@ -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. */