VisibleId
The PS Vita Visible ID is a unique per-console identifyer. It is an extension of the PSP Fuse ID.
Usage
The Visible ID has three main functions: identification, personalization, challenges.
The first function is to uniquely identify a PS Vita console. However, the console mostly uses other identifyers like the Console ID and the Open PSID. The reason is that Visible ID is more predictable than OpenPSID and less descriptive than ConsoleID. However, an advantage of the Visible ID is that it contains the FuseId, which is used in PSPemu and in PSN challenges.
The second function is to allow per-console encryption, aka personalization. From the Visible ID, some per-console keys are derived, like the one that signs IDPS Certificates, and probably also the one that signs SMI.
The third function is to build per-console PSN challenges. A challenge is an encrypted set of data that is sent to PSN. Challenges are built for example in openpsid.prx on PSP and in SceSblGcAuthMgr on PS Vita. It is important to note that these challenges only use the 6 bytes FuseId from the 16 bytes Visible ID, which is probably in order to keep challenge format used for the PSP. See SceSblGcAuthMgr#Challenge.
Note that the Fuse ID is also contained in Cmep keyring 0x602 because it is part of the SceIdStorageSeedValue.
Structure
typedef struct ScePsp2FuseId { // size is 8 bytes char dummy[2]; // constant (00 00) and replaced by constant 10 08 char constant[2]; // constant (01 01) char serial_no[3]; // variable, incrementing serial number in little-endian char model_revision; // seems to always be 00 for PCH-1xxx and PDEL, 01 for PCH-2xxx and PS TV } ScePsp2FuseId; typedef struct ScePsp2VisibleId { ScePsp2FuseId fuse_id; char random[0x18]; } ScePsp2VisibleId;
Note that PSP Fuse ID is only 6 bytes not 8 (2 bytes are always zeroes). This is explained by the fact that the PSP's fuse containing Fuse ID is designed to store 6 bytes of Fuse ID (and probably 2 bytes of Fuse Configuration). And note that PS Vita's Fuse ID has hardcoded bytes, showing again that only 6 bytes are really per-console.
Location
Visible ID is physically contained in some "fuses".
Visible ID is stored in Cmep keyring 0x600.
Visible ID can be obtained directly either by reading Cmep keyring 0x600 with Cmep code execution, or by calling Syscon UART RPC command 0x120.
Visible ID can be obtained less directly with kernel privilege by calling Secure_Modules_Functions#0x3_-_GetVisibleId or SceSblSsMgr#sceSblAimgrGetVisibleIdForDriver.
Visible ID can be obtained less directly with usermode system privileg by calling SceVshBridge#vshSblAimgrGetVisibleId.
Proof that Visible ID contains Fuse ID
Code from openpsid.prx PSP kernel module that generates a challenge:
u32 fuseid0 = *(u32 *)0xBC100090; u32 fuseid1 = *(u32 *)0xBC100094; challenge_work[88] = fuseid1 >> 24; challenge_work[89] = fuseid1 >> 16; challenge_work[90] = fuseid1 >> 8; challenge_work[91] = fuseid1; challenge_work[92] = fuseid0 >> 24; challenge_work[93] = fuseid0 >> 16; challenge_work[94] = fuseid0 >> 8; challenge_work[95] = fuseid0; memcpy(work+0x14, challenge_work, 0x60);
Code from SceSblGcAuthMgr PS Vita kernel module that generates a challenge:
ret = sceSblAimgrGetVisibleIdForDriver(g_visible_id); if ((int)ret < 0) goto fail; challenge_0x60_tmp[88] = 0x10; challenge_0x60_tmp[89] = 8; challenge_0x60_tmp[90] = g_visible_id[2]; challenge_0x60_tmp[91] = g_visible_id[3]; challenge_0x60_tmp[92] = g_visible_id[4]; challenge_0x60_tmp[93] = g_visible_id[5]; challenge_0x60_tmp[94] = g_visible_id[6]; challenge_0x60_tmp[95] = g_visible_id[7];
Samples
Visible ID of Test Subject 9 PS Vita:
00 00 01 01 AC 72 45 00 F5 68 96 03 80 57 C8 1A 25 99 21 A1 73 A4 89 F2 E9 96 23 E9 86 0F 74 2D
Visible ID of some PDEL-100x:
00 00 01 01 3A 60 45 00 C0 26 0E C9 99 12 F1 CB 26 C1 3C BB 8E CE 9C C2 3C A1 11 84 6F 7A 86 F6
Visible ID of some PS Vita Slim or PS TV:
00 00 01 01 78 E8 86 01 61 2E 3A 4A DD E0 41 44 62 D5 2C 05 18 51 9F 00 60 0D 57 36 53 BC 77 C4
Samples of PSP Fuse ID:
- 0x0000590C 26A1828E
Samples of PSP Fuse Configuration (endianness maybe wrong):
- 0x2D00 (TA-085 slim 02g)
- 0x3300 (TA-095v2 09g)