Revocation List
The Revocation List (or Revoke List) contains rules used to determine if a program is revoked (not allowed to load).
Secure Kernel is responsible for parsing and processing of the Revocation List (as part of a check in sceSblACLibIsLoadable
).
Error 0x800F0B30
is returned when attempting to load a revoked program.
Location
There is only one Revocation List file: prog_rvk.srvk
found on the SLB2 partition.
Format
Revocation List contain one or more (variable-sized) Revocation Entries. There is no header or other metadata contained in this file.
?Maybe the CF container has extra SRVK metadata though?
Revocation Entry
Each Revocation Entry contains:
- the condition under which it is applicable (Program Authority ID check)
- the rule under which a program is revoked (if the entry is applicable to program)
Common header
All Revocation Entries share a common header, containing among other the entry's type.
#define REVOCATION_TYPE_PROGRAM_VERSION (1) /* Revoke based on Program Version */ #define REVOCATION_TYPE_PROGRAM_DIGEST (2) /* Revoke based on Program Digest */ struct RevocationCommonHeader { /* Size is 0x14 */ uint16_t type; /*!< One of REVOCATION_TYPE_xxx */ uint16_t; /*!< Padding */ /* Used to check if this entry applies to a given SELF * based on its Program Authority ID (PAID). */ uint64_t PaidValue; uint64_t PaidMask; };
The rule in a relocation entry is processed only if:
((/* PAID of the Program */ & RvkEntry.PaidMask) == RvkEntry.PaidValue)
Version-based revocation entry
There entries are used to revoke programs based on the Program Version.
If the comparison between the version contained in the program and the Revocation Entry is successful, the program has been revoked and cannot be loaded.
struct ProgramVersionRevocation { /* Size is 0x20 */ struct RevocationCommonHeader header; /*!< header.type = 1 */ uint64_t revocationVersion; /*!< Program Version to use for revoked test */ uint16_t revokeRule; /*!< Rule (comparison type) to use for revoked test */ uint16_t; /*!< Padding */ };
There are 6 supported comparison types:
revokeRule
|
Name | Comparison performed |
---|---|---|
0 | EQUAL
|
revocationVersion == ProgramVersion
|
1 | DIFFERENT
|
revocationVersion != ProgramVersion
|
2 | OLDER_THAN
|
revocationVersion < ProgramVersion
|
3 | OLDER_OR_EQUAL
|
revocationVersion <= ProgramVersion
|
4 | NEWER_THAN
|
revocationVersion > ProgramVersion
|
5 | NEWER_OR_EQUAL
|
revocationVersion >= ProgramVersion
|
Digest-based revocation entry
There entries are used to revoke a specific program.
If a program's digest matches one of these entry, it has been revoked and cannot be loaded.
struct ProgramDigestRevocation { /* Size is 0x34 */ struct RevocationCommonHeader header; /*!< header.type = 2 */ uint8_t revokedDigest[0x10]; /*!< Digest of revoked program */ };
Examples
Note: in the side comments, the PaidMask
and PaidValue
are shortened when all least significant bits are zero (indicated by trailing ..
).
3.600.011 prog_rvk.srvk
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F --------- Entry 0 and 1: block all programs matching (PaidMask 0xFFF0.. | PaidValue 0x2000..) 00000000: 01 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00000010: 00 00 f0 ff 00 00 00 00 60 03 00 00 00 00 00 00 To block all programs, two entries are used with the same PAID filter. 00000020: 01 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 First entry uses EQUAL YYY rule, whereas second entry uses DIFFERENT YYY 00000030: 00 00 f0 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 2 and 3: block all programs matching (PaidMask 0xFFF0.. | PaidValue 0x2300..) 00000040: 01 00 00 00 00 00 00 00 00 00 00 23 00 00 00 00 00000050: 00 00 f0 ff 00 00 00 00 60 03 00 00 00 00 00 00 The value of YYY is irrelevant, as long as it is identical in both rules. 00000060: 01 00 00 00 00 00 00 00 00 00 00 23 00 00 00 00 (However, SCE sets YYY to the SdkVersion when Revocation List was generated) 00000070: 00 00 f0 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 4 and 5: block all programs matching (PaidMask 0xFCF0.. | PaidValue 0x2400..) 00000080: 01 00 00 00 00 00 00 00 00 00 00 24 00 00 00 00 00000090: 00 00 f0 fc 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 000000a0: 01 00 00 00 00 00 00 00 00 00 00 24 00 00 00 00 with one of the following: 0x240, 0x250, 0x260, 0x270 000000b0: 00 00 f0 fc 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 6 and 7: block all programs matching (PaidMask 0x2FF7_80.. | PaidValue 0x2800_00..) --------- with a program version OLDER_THAN 3.000.000 (entry 7) or NEWER_THAN 3.600.000 000000c0: 01 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00 000000d0: 00 80 f7 2f 00 00 00 00 60 03 00 00 04 00 00 00 This Mask/Value pair blocks programs whose PAID start 000000e0: 01 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00 with one of the following: 0x2800_0, 0x2808_0 000000f0: 00 80 f7 2f 00 00 00 00 00 03 00 00 02 00 00 00 --------- Entry 8 and 9: blocks all programs matching (PaidMask 0xFFF6.. | PaidValue 0x2802..) 00000100: 01 00 00 00 00 00 00 00 00 00 02 28 00 00 00 00 00000110: 00 00 f6 ff 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 00000120: 01 00 00 00 00 00 00 00 00 00 02 28 00 00 00 00 with one of the following: 0x2802, 0x2803, 0x280A, 0x280B 00000130: 00 00 f6 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 10 and 11: blocks all programs matching (PaidMask 0xFFF6.. | PaidValue 0x2804..) 00000140: 01 00 00 00 00 00 00 00 00 00 04 28 00 00 00 00 00000150: 00 00 f6 ff 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 00000160: 01 00 00 00 00 00 00 00 00 00 04 28 00 00 00 00 with one of the following: 0x2804, 0x2805, 0x280C, 0x280D 00000170: 00 00 f6 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 12 and 13: blocks all programs matching (PaidMask 0xFFF6.. | PaidValue 0x2806..) 00000180: 01 00 00 00 00 00 00 00 00 00 06 28 00 00 00 00 00000190: 00 00 f6 ff 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 000001a0: 01 00 00 00 00 00 00 00 00 00 06 28 00 00 00 00 with one of the following: 0x2806, 0x2807, 0x280E, 0x280F 000001b0: 00 00 f6 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 14 and 15: blocks all programs matching (PaidMask 0xFFF0.. | PaidValue 0x2900..) 000001c0: 01 00 00 00 00 00 00 00 00 00 00 29 00 00 00 00 000001d0: 00 00 f0 ff 00 00 00 00 60 03 00 00 00 00 00 00 000001e0: 01 00 00 00 00 00 00 00 00 00 00 29 00 00 00 00 000001f0: 00 00 f0 ff 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 16 and 17: blocks all programs matching (PaidMask 0xFEF0.. | PaidValue 0x2A00..) 00000200: 01 00 00 00 00 00 00 00 00 00 00 2a 00 00 00 00 00000210: 00 00 f0 fe 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 00000220: 01 00 00 00 00 00 00 00 00 00 00 2a 00 00 00 00 with one of the following: 0x2A0, 0x2B0 00000230: 00 00 f0 fe 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 18 and 19: blocks all programs matching (PaidMask 0xFEF0.. | PaidValue 0x2C00..) 00000240: 01 00 00 00 00 00 00 00 00 00 00 2c 00 00 00 00 00000250: 00 00 f0 fe 00 00 00 00 60 03 00 00 00 00 00 00 This Mask/Value pair blocks programs whose PAID start 00000260: 01 00 00 00 00 00 00 00 00 00 00 2c 00 00 00 00 with one of the following: 0x2C0, 0x2D0 00000270: 00 00 f0 fe 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 20: blocks all programs matching (PaidMask 0xFFF0.. | PaidValue 0x2E00..) with a program version DIFFERENT from 3.600.000 00000280: 01 00 00 00 00 00 00 00 00 00 00 2e 00 00 00 00 This prevents loading any Secure Module from a different firmware. 00000290: 00 00 f0 2f 00 00 00 00 60 03 00 00 01 00 00 00 --------- Entry 21: blocks program with PAID 0x210000101CD20007 (PaidMask = all FFs) NEWER_OR_EQUAL to 0.000.000 000002a0: 01 00 00 00 07 00 d2 1c 10 00 00 21 ff ff ff ff Revokes PlayStation®Mobile Development Assistant 000002b0: ff ff ff ff 00 00 00 00 00 00 00 00 05 00 00 00 (TitleID: PCSI00007) --------- Entry 22: blocks program with PAID 0x210000101CD20009 (PaidMask = all FFs) NEWER_OR_EQUAL to 0.000.000 000002c0: 01 00 00 00 09 00 d2 1c 10 00 00 21 ff ff ff ff Revokes PlayStation®Mobile Development Assistant for Unity 000002d0: ff ff ff ff 00 00 00 00 00 00 00 00 05 00 00 00 (TitleID: PCSI00009) --------- Entry 23: blocks program with PAID 0x2800C0101CD2000B (PaidMask = all FFs) OLDER_THAN 1.220.000 000002e0: 01 00 00 00 0b 00 d2 1c 10 c0 00 28 ff ff ff ff Revokes old versions of PSM Runtime 000002f0: ff ff ff ff 00 00 00 00 22 01 01 00 02 00 00 00 (TitleID: PCSI00011) --------- Entry 24: blocks program with PAID 0x2808000000000101 (PaidMask = all FFs) OLDER_THAN 2.050.000 00000300: 01 00 00 00 01 01 00 00 00 00 08 28 ff ff ff ff Revokes old versions of vs0:/app/NPXS10028/pcff.skprx 00000310: ff ff ff ff 00 00 00 00 05 02 00 00 02 00 00 00 (SceSblPcffBin | PSP Compatibility Flash Files) --------- Entry 25: blocks program with PAID 0x2800000000000013 (PaidMask = all FFs) OLDER_THAN 2.050.000 00000320: 01 00 00 00 13 00 00 00 00 00 00 28 ff ff ff ff Revokes old versions of ScePspemu (vs0:app/NPXS10028/eboot.bin) 00000330: ff ff ff ff 00 00 00 00 05 02 00 00 02 00 00 00 (TitleID: NPXS10028) --------- Entry 26: blocks program with PAID 0x2808000000000100 (PaidMask = all FFs) OLDER_THAN 2.050.000 00000340: 01 00 00 00 00 01 00 00 00 00 08 28 ff ff ff ff Revokes old versions of os0:kd/pcbc.skprx 00000350: ff ff ff ff 00 00 00 00 05 02 00 00 02 00 00 00 (SceSblPcbcBin | PSP Compatibility Boot Code)