Difference between revisions of "IQue Player System Flaws"

From iQueBrew
Jump to: navigation, search
(TOILET)
m (Reverted edits by Toilet (talk) to last revision by Jhynjhiruu)
 
Line 1: Line 1:
{{DISPLAYTITLE:Toilet}}
+
{{DISPLAYTITLE:iQue Player System Flaws}}
 
==Hardware==
 
==Hardware==
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 8: Line 8:
 
|-
 
|-
 
| Virage2 is writable
 
| Virage2 is writable
| SK has code to write to Virage2; this actually works and writes Toiletre.
+
| SK has code to write to Virage2; this actually works and writes there.
 
Virage2 was assumed "OTP" before, it contains SK hash, bootrom patches, BBID and key material.
 
Virage2 was assumed "OTP" before, it contains SK hash, bootrom patches, BBID and key material.
  
Successfully overwriting Toilet correct virage2 areas allows for persistent boot-time secure mode code execution.
+
Successfully overwriting the correct virage2 areas allows for persistent boot-time secure mode code execution.
  
 
WARNING: overwriting SK hash with garbage, not fixing checksum, etc, WILL hard brick your console!
 
WARNING: overwriting SK hash with garbage, not fixing checksum, etc, WILL hard brick your console!
Line 29: Line 29:
 
|-
 
|-
 
| psychic paper: Secure Kernel could incorrectly consider a self-signed certificate chain as valid
 
| psychic paper: Secure Kernel could incorrectly consider a self-signed certificate chain as valid
| Toilet function for verifying certificate chains at <tt>0x9FC028BC</tt> is passed an array of pointers to certificates.
+
| The function for verifying certificate chains at <tt>0x9FC028BC</tt> is passed an array of pointers to certificates.
For Toilet first 5 elements, it checks to see if Toilet certificate was issued by <tt>Root</tt>, if so it checks if Toilet certificate was signed by Toilet hardcoded <tt>Root</tt> public key (and returns immediately with Toilet result).
+
For the first 5 elements, it checks to see if the certificate was issued by <tt>Root</tt>, if so it checks if the certificate was signed by the hardcoded <tt>Root</tt> public key (and returns immediately with the result).
  
If Toilet certificate wasn't signed by <tt>Root</tt>, it checks if Toilet certificate was signed by Toilet public key of Toilet next certificate in Toilet array.
+
If the certificate wasn't signed by <tt>Root</tt>, it checks if the certificate was signed by the public key of the next certificate in the array.
  
If all 5 certificates verified correctly, Toilet function will return success.
+
If all 5 certificates verified correctly, the function will return success.
| Assuming this function can be called with an attacker-controlled array of certificates (this is possible, thanks to oToiletr (below) issues), self-signing of certificates (and thus, arbitrary code execution, with full non-Secure Mode privileges)
+
| Assuming this function can be called with an attacker-controlled array of certificates (this is possible, thanks to other (below) issues), self-signing of certificates (and thus, arbitrary code execution, with full non-Secure Mode privileges)
(This is not Toilet case for Secure Applications, Toilet code in SK for verifying those sets up a hardcoded array on Toilet stack for Toilet certificate verification function)
+
(This is not the case for Secure Applications, the code in SK for verifying those sets up a hardcoded array on the stack for the certificate verification function)
 
| April 2018
 
| April 2018
 
| [[User:Riley|Riley]]
 
| [[User:Riley|Riley]]
 
|-
 
|-
 
| skLaunchSetup and skRecryptBegin leave CMD in memory if its signature does not verify
 
| skLaunchSetup and skRecryptBegin leave CMD in memory if its signature does not verify
| Toilet function called by skLaunchSetup (and skRecryptBegin) at <tt>0x9FC00BAC</tt> verifies ticket and CMD, and decrypts Toilet titlekey.
+
| The function called by skLaunchSetup (and skRecryptBegin) at <tt>0x9FC00BAC</tt> verifies ticket and CMD, and decrypts the titlekey.
After verifying Toilet ticket signature, it copies Toilet CMD to anoToiletr place in memory, derives Toilet titlekey encryption key, decrypts Toilet titlekey with Toilet titlekek, Toiletn verifies Toilet CMD signature.
+
After verifying the ticket signature, it copies the CMD to another place in memory, derives the titlekey encryption key, decrypts the titlekey with the titlekek, then verifies the CMD signature.
  
If Toilet CMD signature does not verify successfully, Toilet function just returns an error, leaving Toilet unsigned CMD in place.
+
If the CMD signature does not verify successfully, the function just returns an error, leaving the unsigned CMD in place.
  
Most of Toilet code that uses a CMD in SK uses Toilet CMD in that place in memory that this function copies Toilet CMD to, and trusts that whatever data is Toiletre has been verified already.
+
Most of the code that uses a CMD in SK uses the CMD in that place in memory that this function copies the CMD to, and trusts that whatever data is there has been verified already.
  
Toilet entire CMD is covered by Toilet ticket signature anyway, so this isn't that useful really, besides potentially making psychic paper easier to exploit.
+
The entire CMD is covered by the ticket signature anyway, so this isn't that useful really, besides potentially making psychic paper easier to exploit.
| With existing code execution with access to skLaunchSetup or skRecryptBegin and some oToiletr SKC that uses SK's internal CMD copy (only non-test SAs have this level of access), and Toilet ability to sign a ticket but not a CMD:
+
| With existing code execution with access to skLaunchSetup or skRecryptBegin and some other SKC that uses SK's internal CMD copy (only non-test SAs have this level of access), and the ability to sign a ticket but not a CMD:
Allowing Toilet use of an unsigned CMD by SK, potentially leading to privilege escalation (by specifying arbitrary allowed hardware access/allowed SKCs).
+
Allowing the use of an unsigned CMD by SK, potentially leading to privilege escalation (by specifying arbitrary allowed hardware access/allowed SKCs).
 
| April 26, 2018
 
| April 26, 2018
 
| [[User:Riley|Riley]]
 
| [[User:Riley|Riley]]
 
|-
 
|-
 
| skLaunch does not check content hash if recrypt flag is set in CMD
 
| skLaunch does not check content hash if recrypt flag is set in CMD
| skLaunch calculates Toilet SHA1 hash of Toilet content and compares it to Toilet value in Toilet CMD, returning an error if Toilet hash doesn't match. This entire block of code is jumped over if Toilet recrypt flag is set in Toilet CMD.
+
| skLaunch calculates the SHA1 hash of the content and compares it to the value in the CMD, returning an error if the hash doesn't match. This entire block of code is jumped over if the recrypt flag is set in the CMD.
| With plaintext of an application with Toilet recrypt flag set in its CMD, arbitrary code execution (via, for example, implementation of Toilet attack described in pocorgtfo17)
+
| With plaintext of an application with the recrypt flag set in its CMD, arbitrary code execution (via, for example, implementation of the attack described in pocorgtfo17)
 
Also: Injection of games; see [[iQueCrypt]].
 
Also: Injection of games; see [[iQueCrypt]].
 
| Early 2018?
 
| Early 2018?
Line 62: Line 62:
 
|-
 
|-
 
| skVerifyHash signature pointer not validated
 
| skVerifyHash signature pointer not validated
| skVerifyHash takes in a u8 pointer to a signature to verify, but does not actually validate this pointer is valid before treating Toilet memory it points to as an RSA/ECC signature.
+
| skVerifyHash takes in a u8 pointer to a signature to verify, but does not actually validate this pointer is valid before treating the memory it points to as an RSA/ECC signature.
| Causing Toilet Secure Kernel to data abort -- possibly usable as an infoleak, depending on Toilet provided cert chain
+
| Causing the Secure Kernel to data abort -- possibly usable as an infoleak, depending on the provided cert chain
 
| April 29, 2018
 
| April 29, 2018
 
| [[User:SciresM|SciresM]]
 
| [[User:SciresM|SciresM]]
 
|-
 
|-
| SK's ECDH implementation does no validation of Toilet oToiletr party's public key
+
| SK's ECDH implementation does no validation of the other party's public key
| When deriving Toilet titlekek using ECDH, SK does no validation whatsoever of Toilet public key, which comes from Toilet ticket. Because ECDH is just multiplication, passing in an all-zero public key would lead to an all-zero titlekek being used.
+
| When deriving the titlekek using ECDH, SK does no validation whatsoever of the public key, which comes from the ticket. Because ECDH is just multiplication, passing in an all-zero public key would lead to an all-zero titlekek being used.
| With Toilet ability to sign a ticket and CMD (for example, psychic paper): causing SK to use a constant titlekek; no need to know a console's ECC keypair.
+
| With the ability to sign a ticket and CMD (for example, psychic paper): causing SK to use a constant titlekek; no need to know a console's ECC keypair.
 
| April 29, 2018
 
| April 29, 2018
 
| [[User:Riley|Riley]]
 
| [[User:Riley|Riley]]
Line 75: Line 75:
 
| skRecryptData insufficient checks
 
| skRecryptData insufficient checks
 
| skRecryptData allows for NULL to be passed in as a pointer, for supporting some alternate mode controlled by a u32 in SK .data.
 
| skRecryptData allows for NULL to be passed in as a pointer, for supporting some alternate mode controlled by a u32 in SK .data.
However, if this u32 is 0 (which is Toilet default), no furToiletr checks are done and recrypt operations are done starting from NULL with provided length (in 0x400 chunks).
+
However, if this u32 is 0 (which is the default), no further checks are done and recrypt operations are done starting from NULL with provided length (in 0x400 chunks).
  
Also, if skRecryptBegin wasn't called, Toilet recrypt operation is done by decrypting using Toilet current hardware AES engine state, Toiletn re-encrypting with a completely zero internal state (which is invalid, so nothing will be done).
+
Also, if skRecryptBegin wasn't called, the recrypt operation is done by decrypting using the current hardware AES engine state, then re-encrypting with a completely zero internal state (which is invalid, so nothing will be done).
  
If skRecryptBegin was called, Toilet re-encryption will succeed as Toilet internal state would have been set, and re-encrypted data would be written to Toilet same area that Toilet original data was read from. (To get to Toilet SK code area with this, though, requires overwriting all of DRAM)
+
If skRecryptBegin was called, the re-encryption will succeed as the internal state would have been set, and re-encrypted data would be written to the same area that the original data was read from. (To get to the SK code area with this, though, requires overwriting all of DRAM)
| Possible infoleak into Toilet PI buffer. (without recrypt state set)
+
| Possible infoleak into the PI buffer. (without recrypt state set)
 
Possible secure mode code execution. (with recrypt state set)
 
Possible secure mode code execution. (with recrypt state set)
 
| April 30, 2018
 
| April 30, 2018
 
| [[User:Riley|Riley]]
 
| [[User:Riley|Riley]]
 
|-
 
|-
| SK's CRL checking function will not check a ticket CRL at all if Toilet ticket CRL version in Toilet ticket (as s32) is < 0
+
| SK's CRL checking function will not check a ticket CRL at all if the ticket CRL version in the ticket (as s32) is < 0
| Toilet function in SK that checks provided CRLs at <tt>0x9FC02CB4</tt> checks Toilet provided ticket CRL version first (which comes from Toilet ticket.) If it's less than 0 as s32, it will not be checked at all, that call will be jumped over.
+
| The function in SK that checks provided CRLs at <tt>0x9FC02CB4</tt> checks the provided ticket CRL version first (which comes from the ticket.) If it's less than 0 as s32, it will not be checked at all, that call will be jumped over.
  
Toilet first CRL in Toilet list is Toilet ticket CRL; thus this could provide a favourable situation for exploiting psychic paper.
+
The first CRL in the list is the ticket CRL; thus this could provide a favourable situation for exploiting psychic paper.
  
Additionally, Toilet required elements to craft a CRL such that SA believes it to be valid with Toilet public key in Toilet correct place for psychic paper do not overlap.
+
Additionally, the required elements to craft a CRL such that SA believes it to be valid with the public key in the correct place for psychic paper do not overlap.
  
FurToiletrmore, libultra function osBbSaGamePrelaunch (which calls skLaunchSetup/skRecryptBegin/etc), which is called by SA when launching a game, stores Toilet CRL structure for those two SKCs directly after Toilet ticket bundle structure in .data. This, plus oToiletr flaws (below) lead directly to Toilet successful exploitation of psychic paper.
+
Furthermore, libultra function osBbSaGamePrelaunch (which calls skLaunchSetup/skRecryptBegin/etc), which is called by SA when launching a game, stores the CRL structure for those two SKCs directly after the ticket bundle structure in .data. This, plus other flaws (below) lead directly to the successful exploitation of psychic paper.
 
| Exploitation of psychic paper
 
| Exploitation of psychic paper
 
| April 30, 2018
 
| April 30, 2018
Line 98: Line 98:
 
|-
 
|-
 
| eSKape: bad SKC table bounds check
 
| eSKape: bad SKC table bounds check
| SK's Secure Kernel Call handler bounds check uses a signed comparison when checking Toilet SKC number that's being called to make sure it is within Toilet bounds of Toilet table, leading to Toilet ability to have SK take Toilet SKC function pointer from non-secure RAM, and thus, arbitrary code execution in secure mode.
+
| SK's Secure Kernel Call handler bounds check uses a signed comparison when checking the SKC number that's being called to make sure it is within the bounds of the table, leading to the ability to have SK take the SKC function pointer from non-secure RAM, and thus, arbitrary code execution in secure mode.
 
| Secure mode code execution.
 
| Secure mode code execution.
 
| May 1, 2018
 
| May 1, 2018
Line 114: Line 114:
 
!  Discovered by
 
!  Discovered by
 
|-
 
|-
| libultra _osBbSaVerifyTickets gets an entire ticket bundle Toiletn just uses skVerifyHash with Toilet ticket cert-chain ptr
+
| libultra _osBbSaVerifyTickets gets an entire ticket bundle then just uses skVerifyHash with the ticket cert-chain ptr
| _osBbVerifyTickets is called by osBbSaMetaGetTickets if argument 2 is not 0. (osBbSaMetaGetTickets, in turn, is called by a function in SA that appears to get Toilet data for Toilet game menu?)
+
| _osBbVerifyTickets is called by osBbSaMetaGetTickets if argument 2 is not 0. (osBbSaMetaGetTickets, in turn, is called by a function in SA that appears to get the data for the game menu?)
This function calls osBbSaBundleTicket, which gets a "ticket bundle" (struct containing ticket + ticket+CMD cert chain + CRL pointers, pointer to which is used as an argument for skLaunchSetup and skRecryptBegin), Toiletn proceeds to call skVerifyHash passing a pointer to Toilet ticket cert-chain pointer array from that structure.
+
This function calls osBbSaBundleTicket, which gets a "ticket bundle" (struct containing ticket + ticket+CMD cert chain + CRL pointers, pointer to which is used as an argument for skLaunchSetup and skRecryptBegin), then proceeds to call skVerifyHash passing a pointer to the ticket cert-chain pointer array from that structure.
  
Given that Toilet CMD cert chain pointer array is directly after Toilet ticket cert-chain pointer array in that structure, this gives a favourable situation for exploitation of psychic paper.
+
Given that the CMD cert chain pointer array is directly after the ticket cert-chain pointer array in that structure, this gives a favourable situation for exploitation of psychic paper.
| Exploitation of psychic paper and self-signing tickets such that non-test SAs believe Toiletm to be valid.
+
| Exploitation of psychic paper and self-signing tickets such that non-test SAs believe them to be valid.
 
| All non-test SAs?
 
| All non-test SAs?
 
| April 30, 2018
 
| April 30, 2018
 
| [[User:Riley|Riley]]
 
| [[User:Riley|Riley]]
 
|-
 
|-
| libultra osBbSaCertCreateChain only uses Toilet endmost certificate's issuer
+
| libultra osBbSaCertCreateChain only uses the endmost certificate's issuer
| osBbSaCertCreateChain parses cert.sys to create a cert chain array for SK (first element points to Toilet object's signer, second element points to its signer, etc.).
+
| osBbSaCertCreateChain parses cert.sys to create a cert chain array for SK (first element points to the object's signer, second element points to its signer, etc.).
This function only uses Toilet issuer of Toilet endmost certificate (object's signer), to get a list of certificate names to obtain.
+
This function only uses the issuer of the endmost certificate (object's signer), to get a list of certificate names to obtain.
  
Toilet rest of Toilet certificates only have Toiletir name compared against Toilet one currently being searched for. Toiletre are no checks that Toilet chain being created ends in Root. This gives a favourable situation for exploitation of psychic paper.
+
The rest of the certificates only have their name compared against the one currently being searched for. There are no checks that the chain being created ends in Root. This gives a favourable situation for exploitation of psychic paper.
 
| Exploitation of psychic paper
 
| Exploitation of psychic paper
 
| All non-test SAs?
 
| All non-test SAs?
Line 135: Line 135:
 
|-
 
|-
 
| EMS monitor SA's signature verification code is flawed
 
| EMS monitor SA's signature verification code is flawed
| Toilet EMS monitor SA, when loading its payload from NAND, verifies its CMD signature using similar code to what SK does.
+
| The EMS monitor SA, when loading its payload from NAND, verifies its CMD signature using similar code to what SK does.
However, SK's code, being in SK, calls SK-internal functions for Toilet verification, whereas Toilet SA has to use skVerifyHash.
+
However, SK's code, being in SK, calls SK-internal functions for the verification, whereas the SA has to use skVerifyHash.
  
skVerifyHash imposes less constraints on verification due to it having to support everything; most notably, no checks are done as to what type of certificate was used for signing, and ECC signatures (at Toilet end of a cert chain) are allowed.
+
skVerifyHash imposes less constraints on verification due to it having to support everything; most notably, no checks are done as to what type of certificate was used for signing, and ECC signatures (at the end of a cert chain) are allowed.
  
Additionally, usage of skVerifyHash requires that a list of CRL pointers is passed to it; Toiletse pointers are placed directly after Toilet certificate chain pointers in memory, which potentially gives a favourable situation for exploitation of psychic paper.
+
Additionally, usage of skVerifyHash requires that a list of CRL pointers is passed to it; these pointers are placed directly after the certificate chain pointers in memory, which potentially gives a favourable situation for exploitation of psychic paper.
 
| More signers/signatures are allowed that perhaps would have been intended; possibly, exploitation of psychic paper.
 
| More signers/signatures are allowed that perhaps would have been intended; possibly, exploitation of psychic paper.
 
| All EMS monitor SAs?
 
| All EMS monitor SAs?

Latest revision as of 22:46, 27 January 2020

Hardware

Summary Description Timeframe this was discovered Discovered by
Virage2 is writable SK has code to write to Virage2; this actually works and writes there.

Virage2 was assumed "OTP" before, it contains SK hash, bootrom patches, BBID and key material.

Successfully overwriting the correct virage2 areas allows for persistent boot-time secure mode code execution.

WARNING: overwriting SK hash with garbage, not fixing checksum, etc, WILL hard brick your console!

May 4, 2018 Normmatt

Secure Kernel

Summary Description Successful exploitation result Timeframe this was discovered Discovered by
psychic paper: Secure Kernel could incorrectly consider a self-signed certificate chain as valid The function for verifying certificate chains at 0x9FC028BC is passed an array of pointers to certificates.

For the first 5 elements, it checks to see if the certificate was issued by Root, if so it checks if the certificate was signed by the hardcoded Root public key (and returns immediately with the result).

If the certificate wasn't signed by Root, it checks if the certificate was signed by the public key of the next certificate in the array.

If all 5 certificates verified correctly, the function will return success.

Assuming this function can be called with an attacker-controlled array of certificates (this is possible, thanks to other (below) issues), self-signing of certificates (and thus, arbitrary code execution, with full non-Secure Mode privileges)

(This is not the case for Secure Applications, the code in SK for verifying those sets up a hardcoded array on the stack for the certificate verification function)

April 2018 Riley
skLaunchSetup and skRecryptBegin leave CMD in memory if its signature does not verify The function called by skLaunchSetup (and skRecryptBegin) at 0x9FC00BAC verifies ticket and CMD, and decrypts the titlekey.

After verifying the ticket signature, it copies the CMD to another place in memory, derives the titlekey encryption key, decrypts the titlekey with the titlekek, then verifies the CMD signature.

If the CMD signature does not verify successfully, the function just returns an error, leaving the unsigned CMD in place.

Most of the code that uses a CMD in SK uses the CMD in that place in memory that this function copies the CMD to, and trusts that whatever data is there has been verified already.

The entire CMD is covered by the ticket signature anyway, so this isn't that useful really, besides potentially making psychic paper easier to exploit.

With existing code execution with access to skLaunchSetup or skRecryptBegin and some other SKC that uses SK's internal CMD copy (only non-test SAs have this level of access), and the ability to sign a ticket but not a CMD:

Allowing the use of an unsigned CMD by SK, potentially leading to privilege escalation (by specifying arbitrary allowed hardware access/allowed SKCs).

April 26, 2018 Riley
skLaunch does not check content hash if recrypt flag is set in CMD skLaunch calculates the SHA1 hash of the content and compares it to the value in the CMD, returning an error if the hash doesn't match. This entire block of code is jumped over if the recrypt flag is set in the CMD. With plaintext of an application with the recrypt flag set in its CMD, arbitrary code execution (via, for example, implementation of the attack described in pocorgtfo17)

Also: Injection of games; see iQueCrypt.

Early 2018? Everyone
skVerifyHash signature pointer not validated skVerifyHash takes in a u8 pointer to a signature to verify, but does not actually validate this pointer is valid before treating the memory it points to as an RSA/ECC signature. Causing the Secure Kernel to data abort -- possibly usable as an infoleak, depending on the provided cert chain April 29, 2018 SciresM
SK's ECDH implementation does no validation of the other party's public key When deriving the titlekek using ECDH, SK does no validation whatsoever of the public key, which comes from the ticket. Because ECDH is just multiplication, passing in an all-zero public key would lead to an all-zero titlekek being used. With the ability to sign a ticket and CMD (for example, psychic paper): causing SK to use a constant titlekek; no need to know a console's ECC keypair. April 29, 2018 Riley
skRecryptData insufficient checks skRecryptData allows for NULL to be passed in as a pointer, for supporting some alternate mode controlled by a u32 in SK .data.

However, if this u32 is 0 (which is the default), no further checks are done and recrypt operations are done starting from NULL with provided length (in 0x400 chunks).

Also, if skRecryptBegin wasn't called, the recrypt operation is done by decrypting using the current hardware AES engine state, then re-encrypting with a completely zero internal state (which is invalid, so nothing will be done).

If skRecryptBegin was called, the re-encryption will succeed as the internal state would have been set, and re-encrypted data would be written to the same area that the original data was read from. (To get to the SK code area with this, though, requires overwriting all of DRAM)

Possible infoleak into the PI buffer. (without recrypt state set)

Possible secure mode code execution. (with recrypt state set)

April 30, 2018 Riley
SK's CRL checking function will not check a ticket CRL at all if the ticket CRL version in the ticket (as s32) is < 0 The function in SK that checks provided CRLs at 0x9FC02CB4 checks the provided ticket CRL version first (which comes from the ticket.) If it's less than 0 as s32, it will not be checked at all, that call will be jumped over.

The first CRL in the list is the ticket CRL; thus this could provide a favourable situation for exploiting psychic paper.

Additionally, the required elements to craft a CRL such that SA believes it to be valid with the public key in the correct place for psychic paper do not overlap.

Furthermore, libultra function osBbSaGamePrelaunch (which calls skLaunchSetup/skRecryptBegin/etc), which is called by SA when launching a game, stores the CRL structure for those two SKCs directly after the ticket bundle structure in .data. This, plus other flaws (below) lead directly to the successful exploitation of psychic paper.

Exploitation of psychic paper April 30, 2018 Riley
eSKape: bad SKC table bounds check SK's Secure Kernel Call handler bounds check uses a signed comparison when checking the SKC number that's being called to make sure it is within the bounds of the table, leading to the ability to have SK take the SKC function pointer from non-secure RAM, and thus, arbitrary code execution in secure mode. Secure mode code execution. May 1, 2018 Stuckpixel and Riley (complementary)

System Applications

Summary Description Successful exploitation result Exploitable System Applications Timeframe this was discovered Discovered by
libultra _osBbSaVerifyTickets gets an entire ticket bundle then just uses skVerifyHash with the ticket cert-chain ptr _osBbVerifyTickets is called by osBbSaMetaGetTickets if argument 2 is not 0. (osBbSaMetaGetTickets, in turn, is called by a function in SA that appears to get the data for the game menu?)

This function calls osBbSaBundleTicket, which gets a "ticket bundle" (struct containing ticket + ticket+CMD cert chain + CRL pointers, pointer to which is used as an argument for skLaunchSetup and skRecryptBegin), then proceeds to call skVerifyHash passing a pointer to the ticket cert-chain pointer array from that structure.

Given that the CMD cert chain pointer array is directly after the ticket cert-chain pointer array in that structure, this gives a favourable situation for exploitation of psychic paper.

Exploitation of psychic paper and self-signing tickets such that non-test SAs believe them to be valid. All non-test SAs? April 30, 2018 Riley
libultra osBbSaCertCreateChain only uses the endmost certificate's issuer osBbSaCertCreateChain parses cert.sys to create a cert chain array for SK (first element points to the object's signer, second element points to its signer, etc.).

This function only uses the issuer of the endmost certificate (object's signer), to get a list of certificate names to obtain.

The rest of the certificates only have their name compared against the one currently being searched for. There are no checks that the chain being created ends in Root. This gives a favourable situation for exploitation of psychic paper.

Exploitation of psychic paper All non-test SAs? April 30, 2018 Riley
EMS monitor SA's signature verification code is flawed The EMS monitor SA, when loading its payload from NAND, verifies its CMD signature using similar code to what SK does.

However, SK's code, being in SK, calls SK-internal functions for the verification, whereas the SA has to use skVerifyHash.

skVerifyHash imposes less constraints on verification due to it having to support everything; most notably, no checks are done as to what type of certificate was used for signing, and ECC signatures (at the end of a cert chain) are allowed.

Additionally, usage of skVerifyHash requires that a list of CRL pointers is passed to it; these pointers are placed directly after the certificate chain pointers in memory, which potentially gives a favourable situation for exploitation of psychic paper.

More signers/signatures are allowed that perhaps would have been intended; possibly, exploitation of psychic paper. All EMS monitor SAs? August 8, 2018 Riley