UbuntuでSSDを完全消去(Secure Erase)する

# 概要

Linuxコマンドを用いて，SATA接続のSSDのデータを二度と復元できないように完全消去する方法について紹介します．

注) Secure EraseはSSD内部で行われる操作のため失敗すると最悪の場合SSDが文鎮化します．くれぐれも**自己責任**でお願いします． 

## 検証環境

<dl>
  <dt>OS</dt>
  <dd>Ubuntu Desktop 20.04 LTS</dd>
  <dt>SSD</dt>
  <dd>SANDISK SDSSDH3-1T00-G25</dd>
</dl>

# はじめに (方法だけを知りたい方は飛ばしてください)
## SSDにゼロ埋めは意味がない

一般に，OS上でファイルを削除したとしてもディスク上ですぐに消えるわけではない[^1] ことはご存知かと思います．
そこで，ディスクを破棄するとき・他人に譲るときなどは情報漏えいを防ぐためにディスクの完全消去を実施する必要があります．

HDDの場合は以下のように全てのセクタに0を書き込む作業(通称ゼロ埋め)をすれば解決します．

```bash:ゼロ埋め
dd if=/dev/zero of=/dev/sda
```

しかし，SSDはブロック単位でデータを扱うのでHDDと仕組みが異なる上に，ウェアレベリングというSSDの寿命を向上させるための技術[^2] が搭載されているため，**上記のような方法では正しく上書きできません．**

このため，近年のSSDにはSSD自らデータの完全消去を行うための仕組みである**Secure Erase**が搭載されています．

## Secure Eraseのしくみ

Secure EraseはSSDに内蔵された機能であり，これを外から呼び出すことによって使用します．

SSDのコントローラの内部には「どの位置にどのデータを記録したか」の対応を記憶しておくマッピングテーブルと呼ばれるものが搭載されています．
Secure Eraseの実行命令が来ると，SSDはこのマッピングテーブルを消去することによってフラッシュメモリに保存されたデータの読み取り方を忘れ，解読ができない状態にします．また，Enhanced Secure Erase[^3] に対応したSSDの場合は，ウェアレベリングを解除した後に全ブロックを消去することができます．

# 作業手順

## 1. 準備

まず，SSDを**USB-SATAなどの変換端子を用いずに**SATAケーブルによってマザーボードに直接マウントします．[^4]

ターミナルにおいて`ls -l /dev/sd*`を実行し，目的のSSDのデバイスファイルを確認してください．以下では`/dev/sdb`であったものとして進めます．

次に，SSDの状態を確認するため，以下のコマンドを実行します．

```bash:SSDの情報を出力
hdparm -I /dev/sdb
```

すると以下のような出力を得ます．

```bash:hdparmの出力
/dev/sdb:

ATA device, with non-removable media
	Model Number:       SANDISK SDSSDH3-1T00-G25                 
	Serial Number:      XXXXXXXXXXXXX    
	Firmware Revision:  XXXXXXX
	Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0
Standards:
	Used: unknown (minor revision code 0x0110) 
	Supported: 8 7 6 5 
	Likely used: 8

(中略)

Security: 
	Master password revision code = 12345
		supported
	not	enabled
	not	locked
		frozen
	not	expired: security count
		supported: enhanced erase
	2min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.
```

上記の最後にある"Security"に注目してください．それぞれの項目の意味は，

- `enabled`: SSDのセキュリティ機能がONになっているかどうか
- `frozen`: SSDがSecure Eraseが実行できないように保護されているかどうか
- `locked`: SSDがパスワードでロックされているかどうか
- `supported: enhanced erase` : 表示される場合はEnhanced Secure Eraseに対応している 
- `x min for ~`: Secure Erase, Enhanced Secure Eraseにかかる時間の予想

となっています．Secure Eraseは，悪意あるプログラムなどに勝手に実行されないために通常状態では制限がかかっており，まずはこの制限を解除する必要があります．

実際に今回の出力ではSSDが`frozen`になってしまっています．これは一旦Ubuntuをサスペンドして再びログインすることで解除できます．

```bash:サスペンド
sudo systemctl suspend
```

復帰したら再び`hdparm -I /dev/sdb`を実行し，`not frozen`となっていることを確認してください．

## 2. 消去の実行

まずはSSDにパスワードを設定する必要があります．正常にSecure Eraseが完了した場合はこのパスワードは消去後にリセットされるため適当なものでOKです．

```bash:パスワード設定
hdparm --user-master u --security-set-pass <パスワード> /dev/sdb
```
成功すると以下のような出力を得ます．

```bash:パスワード設定完了
security_password=<パスワード>
/dev/sdb:
Issuing SECURITY_SET_PASS command, password=<パスワード>, user=user, mode=high
```

`hdparm -I /dev/sdb`を実行し，Securityが`enabled`となっていることを確認してください．


最後に，1. で確認したSSDの機能に応じて，Secure EraseかEnhanced Secure Eraseを開始します．

```bash:SecureEraseの実行
hdparm --user-master u --security-erase <パスワード> /dev/sdb
```

```bash:EnhancedSecureEraseの実行
hdparm --user-master u --yes-i-know-what-i-am-doing --sanitize-block-erase <パスワード> /dev/sdb
```

あとは終了するのを待ちます．Enhanced Secure Eraseの場合は

```bash:進捗状況確認
hdparm --sanitize-status /dev/sdb
```
を実行することで進捗が確認できます．

これでディスクは一切復元できなくなりました．お疲れ様でした．

# ハマったところ

## SSDにパスワードを設定できない

`hdparm --user-master u --security-set-pass`を実行すると，

```bash:パスワード設定時のエラー
SG_IO: bad/missing sense data, sb[]: 70 00 05 00 00 00 00 0a 00 ...(略)
```

なるエラーが出てうまく設定できませんでした．

:white_check_mark: SSDをSATA-USB変換ケーブルを使わずに直接接続することで解決しました．

## Secure EraseしたSSDが認識されなくなった

Secure Eraseを実行したあと変換ケーブルを用いてWindowsにUSB接続したところ，デバイスマネージャからは見えるものの"ディスクの管理"では表示されませんでした．Linuxマシンに接続し直して起動後`dmesg`コマンドを実行すると

```bash:カーネルログ
(略)
Buffer I/O error on dev sdb, logical block 0, async page read
ssd I/O error, dev sdb, sector 0 op 0x0:(READ) flags 0x0 phys_seg
(略)
```

のようなI/Oエラーが大量に出ていました．

:white_check_mark: SSDがロックされているためロックを解除し，セキュリティ設定をOFFにする必要があります．

念の為`hdparm -I /dev/sdb`としてSSDが`locked`になっていることを確認した後，

```bash:ロック解除&セキュリティ無効化
hdparm --user-master u --security-unlock <設定したパスワード> /dev/sdb
hdparm --user-master u --security-disable <設定したパスワード> /dev/sdb
```

とすることでアクセスできるようになりました．
(Secure Eraseの終了後にパスワードが自動で解除されないことがあるようです)

### 番外編: この記事を書くときにハマったところ

Qiitaにおいて注釈は`[^5]`のように書くことで右上に緑色で表示されます[^5]が，この記事を執筆中はなぜかそのまま`[^5]`と記事中に表示されていました．細かく編集しながら様子を見たところ，複数行のコードブロック中に`~~中略~~`のように波線に囲まれた文字列を別行立てで書くと注釈文字としての設定が解除されてしまうようです．~~30分返せ~~

[^1]: 株式会社バッファロー，データ復旧はなぜ可能？データ消去はなぜ必要？HDDのデータ保存と削除の仕組み， https://www.buffalo.jp/topics/trouble/detail/recovery_0039.html

[^2]: 株式会社ジャングル，SSDデータ消去の仕組みについて，https://www.diskdeleter.jp/ssd-process/

[^3]: sanitizeとも呼ばれます．

[^4]: Secure Eraseは本来USB-SATA接続でもできるようですが，私の環境ではエラーが出てしまいうまく行きませんでした．

[^5]: 正しい注釈です．