From 9fd61d1453e07cc91cb4b92ecdb0b05bb1191f2e Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Fri, 26 May 2023 07:42:16 +0100 Subject: [PATCH] Ring ATA passwords --- .../pages/sega/software/security/index.html | 2 ++ .../pages/sega/software/security/~ata.md | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 templates/pages/sega/software/security/~ata.md diff --git a/templates/pages/sega/software/security/index.html b/templates/pages/sega/software/security/index.html index 6b1c248..fef591a 100644 --- a/templates/pages/sega/software/security/index.html +++ b/templates/pages/sega/software/security/index.html @@ -32,6 +32,8 @@

This can be bypassed either by extracting the password used, or by first powering on the Ring* system with the drive connected, then hotplugging the SATA data cable on the drive while keeping the drive powered.

+{% markdown %}{% include relative("~ata.md") %}{% endmarkdown %} +
Why does this work?

The following is the sequence of possible security modes for an ATA drive:

diff --git a/templates/pages/sega/software/security/~ata.md b/templates/pages/sega/software/security/~ata.md new file mode 100644 index 0000000..3b6f932 --- /dev/null +++ b/templates/pages/sega/software/security/~ata.md @@ -0,0 +1,30 @@ +The ATA key is derived in the BIOS during boot, based on the 40-byte model number of the drive provided by the ATA identify device data command (0xEC). The 32-byte password is then calculated based on the following algorithm. This algorithm is consistent between RingWide, RingEdge and RingEdge2 (thanks to Darksoft for some info here). Happy unlocking! + +```py +CHARSET = bytearray(b'/-AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789') + +def charset_index(x: int) -> int: + if x in CHARSET: + return CHARSET.index(x) + return 0x55 + +def prepare_password(model: bytes) -> bytes: + assert len(model) == 40 + password = bytearray(32) + + for i in range(32): + a = charset_index(model[i]) + b = charset_index(model[39 - i]) + + if i % 2 == 0: + password[i] = (((i ^ a) & 0x1f) << 3) ^ ((b & 0x2e) >> 1) + else: + password[i] = (((i ^ b) & 0x3b) << 2) ^ ((a & 0x66) >> 1) + + return password +``` + +Some common disks: + +- `GBDriver RS2`: `7242525aba526a5aea726278ca42da4a2a223a2a0a221a2a6a027a0a5cce4a0a` +- `GBDriver RS3`: `7242525aba526a5aea726278ca42da4a2a223a2a0a221a2a6a027a0a5cce4a0a`