Algoritmo Avanzato di Cancellazione Sicura (ASDA)
La prossima generazione di cancellazione sicura dei dati.

ASDA consente una cancellazione dei dati altamente efficace e verificabile con consumo minimo di risorse. I quattro passaggi sono progettati per efficienza e trasparenza: verifica di lettura dopo scrittura (read‑after‑write) e log di cancellazione documentano ogni fase. AES‑256 e numeri casuali crittograficamente robusti rendono molto più difficile la ricostruzione forense. L’implementazione si integra senza attriti nei processi esistenti.
ASDA supera inoltre i requisiti della NIST SP 800‑88 Rev. 1 (Clear / Purge / Destroy). A seconda del supporto (HDD/SSD/Flash), possono essere opportuni meccanismi aggiuntivi di purge, come Block Erase o Cryptographic Erase.
Panoramica dei quattro passaggi
L’area dati viene completamente sovrascritta con 0xFF—i contenuti originali diventano irriconoscibili.
Il contenuto originale nel buffer viene cifrato con AES‑256 e riscritto—creando una barriera crittografica contro la ricostruzione forense. (Le chiavi risiedono solo temporaneamente in RAM e vengono poi cancellate in modo sicuro.)
Si scrive un pattern di bit definito (es.:
10010010 01001001 00100100
), seguito da verifica read‑after‑write. Le deviazioni vengono riscritte e riportate nel registro di cancellazione. Infine, ASDA sovrascrive l’area con numeri casuali crittograficamente forti (CSPRNG secondo NIST SP 800‑90A).
Documentazione sul codice sorgente:
La funzione ASDAErase nella classe DataShredder viene utilizzata per cancellare in modo sicuro i dati da un file. Questo processo prevede quattro fasi, eseguite in ordine sequenziale.
Il primo passo consiste nel sovrascrivere tutti i dati nel file con un modello specifico. Questo viene fatto utilizzando la funzione memset, che imposta un blocco di memoria a un valore specifico.
Il secondo passo è crittografare i dati originali nel file utilizzando l'algoritmo AES a 256 bit (Advanced Encryption Algorithm). Questo viene fatto utilizzando la classe AES, che dispone di un metodo StartEncryption che accetta un array di unsigned char come input. I dati da crittografare vengono passati a questo metodo come argomento.
Il terzo passo prevede la verifica dei dati scritti nel file nel secondo passo. Questo viene fatto leggendo i dati dal file e confrontandoli con i dati originali utilizzando la funzione memcmp. Se i dati letti dal file non corrispondono ai dati originali, viene restituito un valore di stato 0xC0000719L (STATUS_CONTEXT_MISMATCH).
Infine, l'ultimo passo consiste nel sovrascrivere i dati nel file con un modello casuale. Questo viene fatto utilizzando la funzione DoRandomErase, che accetta tre argomenti: la dimensione dei dati da cancellare, un buffer per contenere i dati e un valore di byte che rappresenta il numero di iterazione.
Se tutte e quattro le fasi vengono completate con successo, la funzione ASDAErase restituisce un valore di stato pari a 0. Se una qualsiasi delle fasi fallisce, viene restituito un codice di errore appropriato.
Codice sorgente:
long DataShredder::ASDAErase(DWORD size, byte *buf, byte iteration) { long status=0; LARGE_INTEGER nCurrentFilePointer = {0}; this->m_pLowLevelIO->GetFilePointer(&nCurrentFilePointer); // buffer di lavoro byte *buf1 = (byte*)malloc(size); // lettura del contenuto del file if(iteration == 0) { status=this->m_pLowLevelIO->Read(buf1, size, NULL); this->m_pLowLevelIO->SetFilePointer(&nCurrentFilePointer); } // sovrascrittura con 0xFF if(status == 0) { memset(buf, 0xFF, size); status=this->m_pLowLevelIO->Write(buf, size, NULL); if(!m_noBuffering) this->m_pLowLevelIO->Flush(); this->m_pLowLevelIO->SetFilePointer(&nCurrentFilePointer); } // crittografia del contenuto originale del file if(status == 0) { ULONG K[8]; ULONG seed; seed=GetTickCount(); K[0]=LowLevel::IO::Random(&seed); K[1]=LowLevel::IO::Random(&seed); K[2]=LowLevel::IO::Random(&seed); K[3]=LowLevel::IO::Random(&seed); K[4]=LowLevel::IO::Random(&seed); K[5]=LowLevel::IO::Random(&seed); K[6]=LowLevel::IO::Random(&seed); K[7]=LowLevel::IO::Random(&seed); AES aes; aes.SetParameters(256); aes.StartEncryption((const unsigned char *)K); for(ULONG i=0; (i*4)m_pLowLevelIO->Write(buf, size, NULL); if(!m_noBuffering) this->m_pLowLevelIO->Flush(); this->m_pLowLevelIO->SetFilePointer(&nCurrentFilePointer); } if(status == 0) { byte bData[] = { 0x92,//10010010, 0x49,//01001001, 0x24 //00100100 }; for(DWORD i = 0; i < size; i++) { buf[i] = bData[i%3]; } status=this->m_pLowLevelIO->Write(buf, size, NULL); if(!m_noBuffering) this->m_pLowLevelIO->Flush(); this->m_pLowLevelIO->SetFilePointer(&nCurrentFilePointer); // verifica if(0==this->m_pLowLevelIO->Read(buf1, size, NULL)) { this->m_pLowLevelIO->SetFilePointer(&nCurrentFilePointer); if(memcmp(buf1, buf, size)) { status=0xC0000719L;//STATUS_CONTEXT_MISMATCH; } } else { status=0xC0000719L;//STATUS_CONTEXT_MISMATCH; } } if(status == 0) { status = this->DoRandomErase(size, buf, 0); } free(buf1); return status; }
Spiegazione del codice sorgente:
Questo codice sorgente definisce una funzione chiamata ASDAErase, che accetta tre parametri: un intero size, un puntatore buf a un array di byte e un intero iteration. La funzione restituisce un valore intero status.
La funzione inizia dichiarando e inizializzando alcune variabili. Quindi legge il puntatore del file corrente utilizzando la funzione GetFilePointer di un oggetto della classe LowLevelIO. Alloca quindi memoria per un buffer di lavoro buf1 e legge il contenuto del file in questo buffer utilizzando la funzione Read dello stesso oggetto LowLevelIO.
La funzione quindi sovrascrive i dati nel file con il valore 0xFF scrivendo questo valore nel file utilizzando la funzione Write dell'oggetto LowLevelIO, e poi crittografa il contenuto originale del file utilizzando l'algoritmo AES (Advanced Encryption Standard). Lo fa generando una chiave casuale e impostando i parametri di crittografia AES, quindi crittografando il contenuto del file in blocchi di 4 byte utilizzando la funzione StartEncryption.
La funzione quindi scrive i dati crittografati nel file e successivamente sovrascrive il file con un modello di 0x92, 0x49 e 0x24 ripetuti in quest'ordine. Verifica quindi che i dati siano stati scritti correttamente utilizzando la funzione Read e la funzione memcmp per confrontare i dati nel buffer di lavoro buf1 con i dati del modello in buf.
Se tutte queste operazioni hanno successo, la funzione chiama un'altra funzione chiamata DoRandomErase per sovrascrivere il file con dati casuali. Infine, la funzione libera la memoria allocata per buf1 e restituisce il valore di stato.