Changes

1,667 bytes added ,  21:50, 23 March 2018
no edit summary
Line 1: Line 1:  +
SPL is responsible for handling all cryptographic operations within the system and relaying them to the [[#SMC|Secure Monitor]] when necessary.
 +
 +
During [1.0.0-3.0.2], the only existing services were "csrng" and "spl:". However, in [4.0.0+] the "spl:" service was refactored and split into new services with different permission levels. Each service exposes the IPC command list differently in order to prevent cryptographic operations to take place in the wrong context.
 +
 
= csrng =
 
= csrng =
 
This is "nn::spl::detail::IRandomInterface".
 
This is "nn::spl::detail::IRandomInterface".
Line 10: Line 14:     
== GetRandomBytes ==
 
== GetRandomBytes ==
Takes a type-6 buffer and fills it with random data. Same command for "spl:" and "csrng" services.
+
Takes a type-6 buffer and fills it with random data from [[SMC#GetRandomBytes|GetRandomBytes SMC]]. Same command for "spl:" and "csrng" services.
   −
= spl: =
+
= spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu =
This is "nn::spl::detail::IGeneralInterface".
+
These are "nn::spl::detail::IGeneralInterface", "nn::spl::detail::ICryptoInterface", "nn::spl::detail::IFsInterface", "nn::spl::detail::ISslInterface", "nn::spl::detail::IEsInterface" and "nn::spl::detail::IManuInterface"(?).
    
[2.0.0+] Where previously only one AES engine was utilized, there is now support for 4 of them.
 
[2.0.0+] Where previously only one AES engine was utilized, there is now support for 4 of them.
Line 21: Line 25:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name || Permissions
 +
|-
 +
| 0 || [[#GetConfig]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 +
|-
 +
| 1 || [[#UserExpMod]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 0 || [[#GetConfig]] || Wrapper for [[SMC#GetConfig|GetConfig SMC]].
+
| 2 || [[#GenerateAesKek]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 1 || [[#UserExpMod]] || Speculative name. Wrapper for [[SMC#ExpMod|ExpMod SMC]].
+
| 3 || [[#LoadAesKey]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 2 || [[#GenerateAesKek]] || Wrapper for [[SMC#GenerateAesKek|GenerateAesKek SMC]].
+
| 4 || [[#GenerateAesKey]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 3 || [[#LoadAesKey]] || Wrapper for [[SMC#LoadAesKey|LoadAesKey SMC]].
+
| 5 || [[#SetConfig]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 4 || [[#GenerateAesKey]] || Decrypts 0x10 bytes using AES ECB and uses [[SMC#LoadAesKey|LoadAesKey SMC]] with a fixed Y.
+
| 7 || [[#GetRandomBytes]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 5 || [[#SetConfig]] || Wrapper for [[SMC#SetConfig|SetConfig SMC]].
+
| 9 || [[#LoadSecureExpModKey]] || spl:fs
 
|-
 
|-
| 7 || [[#GetRandomBytes]] || Uses [[SMC#GetRandomBytes|GetRandomBytes SMC]].
+
| 10 || [[#SecureExpMod]] || spl:fs
 
|-
 
|-
| 9 || [[#LoadSecureExpModKey]] || Speculative name. Wrapper for [[SMC#LoadSecureExpModKey|LoadSecureExpModKey SMC]].
+
| 11 || [[#IsDevelopment]] || spl:, spl:mig, spl:fs, spl:ssl spl:es, spl:manu
 
|-
 
|-
| 10 || [[#SecureExpMod]] || Speculative name. Uses [[SMC#SecureExpMod|SecureExpModSMC]].
+
| 12 || [[#GenerateSpecificAesKey]] || spl:fs
 
|-
 
|-
| 11 || [[#IsDevelopment]] ||
+
| 13 || [[#DecryptRsaPrivateKey]] || spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 12 || [[#GenerateSpecificAesKey]] || Wrapper for [[SMC#GenerateSpecificAesKey|GenerateSpecificAesKey SMC]].
+
| 14 || [[#DecryptAesKey]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 13 || [[#DecryptPrivk]] || Speculative name. Wrapper for [[SMC#PrivateRsa|PrivateRsa SMC]].
+
| 15 || [[#DecryptAesCtr]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 14 || [[#DecryptAesKey]] || Decrypts 0x10 bytes using AES ECB and uses [[SMC#LoadAesKey|LoadAesKey SMC]] with fixed X and Y.
+
| 16 || [[#ComputeCmac]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 15 || [[#DecryptAesCtr]] || Wrapper for [[SMC#CryptAes|CryptAes SMC]].
+
| 17 || [[#LoadRsaOaepKey]] || spl:es
 
|-
 
|-
| 16 || [[#ComputeCmac]] || Wrapper for [[SMC#ComputeCmac|ComputeCmac SMC]].
+
| 18 || [[#UnwrapRsaOaepWrappedTitleKey]] || spl:es
 
|-
 
|-
| 17 || [[#LoadRsaOaepKey]] || Speculative name. Wrapper for [[SMC#LoadRsaOaepKey|LoadRsaOaepKey SMC]].
+
| 19 || [[#LoadTitleKey]] || spl:fs
 
|-
 
|-
| 18 || [[#UnwrapRsaOaepWrappedTitleKey]] || Speculative name. Wrapper for [[SMC#UnwrapRsaOaepWrappedTitleKey|UnwrapRsaOaepWrappedTitleKey SMC]].
+
| 20 || [2.0.0+] [[#UnwrapAesWrappedTitleKey ]] || spl:es
 
|-
 
|-
| 19 || [[#LoadTitleKey]] || Wrapper for [[SMC#LoadTitleKey|LoadTitleKey SMC]].
+
| 21 || [2.0.0+] [[#LockAesEngine]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 20 || [2.0.0+] [[#UnwrapAesWrappedTitleKey ]] || Wrapper for [[SMC#UnwrapAesWrappedTitleKey|UnwrapAesWrappedTitleKey SMC]].
+
| 22 || [2.0.0+] [[#UnlockAesEngine]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 21 || [2.0.0+] [[#LockAesEngine]] ||
+
| 23 || [2.0.0+] [[#GetSplWaitEvent]] || spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 22 || [2.0.0+] [[#UnlockAesEngine]] ||
+
| 24 || [3.0.0+] [[#SetSharedData]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 23 || [2.0.0+] [[#GetSplWaitEvent]] ||
+
| 25 || [3.0.0+] [[#GetSharedData]] || spl:, spl:mig, spl:fs, spl:ssl, spl:es, spl:manu
 
|-
 
|-
| 24 || [3.0.0+] [[#SetSharedData]] ||
+
| 26 || [5.0.0+] ImportSslRsaKey || spl:ssl
 
|-
 
|-
| 25 || [3.0.0+] [[#GetSharedData]] ||
+
| 27 || [5.0.0+] SecureExpModWithSslKey || spl:ssl
 +
|-
 +
| 28 || [5.0.0+] ImportEsRsaKey || spl:es
 +
|-
 +
| 29 || [5.0.0+] SecureExpModWithEsKey || spl:es
 +
|-
 +
| 30 || [5.0.0+] EncryptManuRsaKeyForImport || spl:manu
 +
|-
 +
| 31 || [5.0.0+] GetPackage2Hash || spl:fs
 
|}
 
|}
    
== GetConfig ==
 
== GetConfig ==
 +
Wrapper for [[SMC#GetConfig|GetConfig SMC]].
 +
 
Takes a u32 ('''ConfigItem'''), and returns one or more u64s ('''ConfigVal''').
 
Takes a u32 ('''ConfigItem'''), and returns one or more u64s ('''ConfigVal''').
   Line 292: Line 310:     
== UserExpMod ==
 
== UserExpMod ==
 +
Wrapper for [[SMC#ExpMod|ExpMod SMC]].
 +
 
Takes one type-10 (C descriptor) buffer ('''data_out_buf''') and 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''exp_in_buf''' and '''mod_in_buf''').
 
Takes one type-10 (C descriptor) buffer ('''data_out_buf''') and 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''exp_in_buf''' and '''mod_in_buf''').
   Line 297: Line 317:     
== GenerateAesKek ==
 
== GenerateAesKek ==
 +
Wrapper for [[SMC#GenerateAesKek|GenerateAesKek SMC]].
 +
 
Takes a 16-byte EKS ('''Encryption Key Source''') and two words ('''KeyGeneration''' and '''option''') as input.
 
Takes a 16-byte EKS ('''Encryption Key Source''') and two words ('''KeyGeneration''' and '''option''') as input.
'''KeyGeneration''' ranges from 0 to 2.
      
Returns a scrambled sealed KEK ('''Key Encryption Key''' used as '''key_x''').
 
Returns a scrambled sealed KEK ('''Key Encryption Key''' used as '''key_x''').
    
== LoadAesKey ==
 
== LoadAesKey ==
 +
Wrapper for [[SMC#LoadAesKey|LoadAesKey SMC]].
 +
 
Takes a u32 ('''keyslot''') and two 16-byte keys ('''key_x''' and '''key_y''').
 
Takes a u32 ('''keyslot''') and two 16-byte keys ('''key_x''' and '''key_y''').
   Line 312: Line 335:  
Takes a 16-byte KEK ('''key_x''') and a 16-byte encrypted key ('''enc_key''').
 
Takes a 16-byte KEK ('''key_x''') and a 16-byte encrypted key ('''enc_key''').
   −
Generates a new key by decrypting '''enc_key''' with a key generated from the supplied '''key_x''' and a fixed '''key_y'''.
+
Generates a new key by decrypting (AES-ECB) '''enc_key''' with a key generated from the supplied '''key_x''' and a fixed '''key_y''' set with [[SMC#LoadAesKey|LoadAesKey SMC]].
    
[2.0.0+] Previously, it always used engine 0. Now it tries to allocate an engine to be used and returns 0xD01A if they're all busy. When the command is done, the engine is released.
 
[2.0.0+] Previously, it always used engine 0. Now it tries to allocate an engine to be used and returns 0xD01A if they're all busy. When the command is done, the engine is released.
    
== SetConfig ==
 
== SetConfig ==
 +
Wrapper for [[SMC#SetConfig|SetConfig SMC]].
 +
 
Takes a u32 ('''ConfigItem''') and a u64 ('''ConfigVal''').
 
Takes a u32 ('''ConfigItem''') and a u64 ('''ConfigVal''').
   Line 328: Line 353:  
Any other '''ConfigItem''', besides 13, can't be set.
 
Any other '''ConfigItem''', besides 13, can't be set.
   −
== LoadRsaOaepKey ==
+
== LoadSecureExpModKey ==
 +
Wrapper for [[SMC#LoadSecureExpModKey|LoadSecureExpModKey SMC]].
 +
 
 
Takes one type-9 (X descriptor) buffer ('''enc_privk_in_buf'''), a 16-byte KEK ('''key_x'''), a 16-byte key ('''key_y''') and a u32 ('''version''').
 
Takes one type-9 (X descriptor) buffer ('''enc_privk_in_buf'''), a 16-byte KEK ('''key_x'''), a 16-byte key ('''key_y''') and a u32 ('''version''').
 
'''version''' is 0 for normal keys or 1 for extended keys.
 
'''version''' is 0 for normal keys or 1 for extended keys.
Line 334: Line 361:  
Decrypts '''enc_privk_in_buf''' with a key generated from '''key_x''' and '''key_y''' and imports it for later usage.
 
Decrypts '''enc_privk_in_buf''' with a key generated from '''key_x''' and '''key_y''' and imports it for later usage.
   −
== UnwrapRsaOaepWrappedTitleKey ==
+
[5.0.0+] This now calls [[SMC#EncryptRsaKeyForImport|EncryptRsaKeyForImport SMC]] instead.
Takes one type-10 (C descriptor) buffer ('''data_out_buf''') and 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''mod_in_buf''' and '''label_hash_in_buf''').
+
 
 +
== SecureExpMod ==
 +
Takes 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''mod_in_buf''' and '''param0_in_buf''').
   −
Decrypts '''data_in_buf''' into '''data_out_buf''' using the private key imported with [[#UnwrapRsaOaepWrappedTitleKey]] and the supplied '''mod_in_buf'''. Afterwards, verifies RSA-OAEP encoding using '''label_hash_in_buf'''.
+
Uses [[SMC#SecureExpMod|SecureExpMod SMC]] to decrypt '''data_in_buf''' using the private key imported with [[#LoadSecureExpModKey]] and the supplied '''mod_in_buf''' and '''param0_in_buf'''.
   −
Returns an u32 ('''dec_data_size''').
+
Generates and returns a 16-byte sealed titlekey.
    
== IsDevelopment ==
 
== IsDevelopment ==
Line 349: Line 378:     
== GenerateSpecificAesKey ==
 
== GenerateSpecificAesKey ==
 +
Wrapper for [[SMC#GenerateSpecificAesKey|GenerateSpecificAesKey SMC]].
 +
 
Takes a 16-byte seed ('''key_seed''') and two words ('''KeyGeneration''' and '''option''') as input.
 
Takes a 16-byte seed ('''key_seed''') and two words ('''KeyGeneration''' and '''option''') as input.
'''KeyGeneration''' ranges from 0 to 2.
      
Returns a scrambled key ('''key_a''').
 
Returns a scrambled key ('''key_a''').
   −
== DecryptPrivk ==
+
== DecryptRsaPrivateKey ==
 +
Wrapper for [[SMC#DecryptRsaPrivateKey|DecryptRsaPrivateKey SMC]].
 +
 
 
Takes one type-10 (C descriptor) buffer ('''dec_privk_out_buf'''), one type-9 (X descriptor) buffer ('''enc_privk_in_buf'''), a 16-byte KEK ('''key_x'''), a 16-byte key ('''key_y''') and a u32 ('''version''').
 
Takes one type-10 (C descriptor) buffer ('''dec_privk_out_buf'''), one type-9 (X descriptor) buffer ('''enc_privk_in_buf'''), a 16-byte KEK ('''key_x'''), a 16-byte key ('''key_y''') and a u32 ('''version''').
 
'''version''' is 0 for normal keys or 1 for extended keys.
 
'''version''' is 0 for normal keys or 1 for extended keys.
Line 361: Line 393:     
Used by [[SSL_services|SSL]]-sysmodule for TLS client-privk.
 
Used by [[SSL_services|SSL]]-sysmodule for TLS client-privk.
 +
 +
[5.0.0+] This now calls [[SMC#DecryptOrImportRsaKey|DecryptOrImportRsaKey SMC]] instead.
    
== DecryptAesKey ==
 
== DecryptAesKey ==
 
Takes a 16-byte encrypted key ('''enc_key''') and two words ('''KeyGeneration''' and '''option''') as input.
 
Takes a 16-byte encrypted key ('''enc_key''') and two words ('''KeyGeneration''' and '''option''') as input.
'''KeyGeneration''' ranges from 0 to 2.
     −
Decrypts '''enc_key''' with a key generated from fixed '''key_x''' and '''key_y''' and returns a 16-byte decrypted key ('''dec_key''').
+
Decrypts (AES-ECB) '''enc_key''' with a key generated from fixed '''key_x''' and '''key_y''' set with [[SMC#LoadAesKey|LoadAesKey SMC]] and returns a 16-byte decrypted key ('''dec_key''').
    
[2.0.0+] Introduced same engine allocation code as for [[#GenerateAesKey]].
 
[2.0.0+] Introduced same engine allocation code as for [[#GenerateAesKey]].
Line 373: Line 406:  
Takes a type-0x46 (B descriptor) buffer ('''data_out_buf'''), a u32 ('''keyslot'''), a type-0x45 (A descriptor) buffer ('''data_in_buf''') and a 16-byte CTR ('''aes_ctr''').
 
Takes a type-0x46 (B descriptor) buffer ('''data_out_buf'''), a u32 ('''keyslot'''), a type-0x45 (A descriptor) buffer ('''data_in_buf''') and a 16-byte CTR ('''aes_ctr''').
   −
Decrypts '''data_in_buf''' into '''data_out_buf''' using the key set in the specified '''keyslot'''.
+
Uses [[SMC#CryptAes|CryptAes SMC]] to decrypt '''data_in_buf''' into '''data_out_buf''', using the key set in the specified '''keyslot'''.
    
[2.0.0+] Verifies the engine is locked by current session.
 
[2.0.0+] Verifies the engine is locked by current session.
    
== ComputeCmac ==
 
== ComputeCmac ==
 +
Wrapper for [[SMC#ComputeCmac|ComputeCmac SMC]].
 +
 
Takes one type-9 (X descriptor) buffer ('''data_in_buf''') and a u32 ('''type?''').
 
Takes one type-9 (X descriptor) buffer ('''data_in_buf''') and a u32 ('''type?''').
   Line 384: Line 419:  
[2.0.0+] Verifies the engine is locked by current session.
 
[2.0.0+] Verifies the engine is locked by current session.
   −
== LoadSecureExpModKey ==
+
== LoadRsaOaepKey ==
Takes one type-9 (X descriptor) buffer ('''enc_privk_in_buf'''), a 16-byte KEK ('''key_x'''), a 16-byte key ('''key_y''') and a u32 ('''version''').
+
Wrapper for [[SMC#LoadRsaOaepKey|LoadRsaOaepKey SMC]].
'''version''' is 0 for normal keys or 1 for extended keys.
+
 
 +
Takes one type-9 (X descriptor) buffer (enc_privk_in_buf), a 16-byte KEK (key_x), a 16-byte key (key_y) and a u32 (version). version is 0 for normal keys or 1 for extended keys.
 +
 
 +
Decrypts enc_privk_in_buf with a key generated from key_x and key_y and imports it for later usage.
   −
Decrypts '''enc_privk_in_buf''' with a key generated from '''key_x''' and '''key_y''' and imports it for later usage.
+
== UnwrapRsaOaepWrappedTitleKey ==
 +
Wrapper for [[SMC#UnwrapRsaOaepWrappedTitleKey|UnwrapRsaOaepWrappedTitleKey SMC]].
   −
== SecureExpMod ==
+
Takes one type-10 (C descriptor) buffer ('''data_out_buf''') and 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''mod_in_buf''' and '''label_hash_in_buf''').
Takes 3 type-9 (X descriptor) buffers ('''data_in_buf''', '''mod_in_buf''' and '''param0_in_buf''').
     −
Decrypts '''data_in_buf''' using the private key imported with [[#LoadSecureExpModKey]] and the supplied '''mod_in_buf''' and '''param0_in_buf'''.
+
Decrypts '''data_in_buf''' into '''data_out_buf''' using the private key imported with [[#LoadRsaOaepKey]] and the supplied '''mod_in_buf'''. Afterwards, verifies RSA-OAEP encoding using '''label_hash_in_buf'''.
   −
Generates and returns a 16-byte sealed titlekey.
+
Returns an u32 ('''dec_data_size''').
    
== LoadTitleKey ==
 
== LoadTitleKey ==
 +
Wrapper for [[SMC#LoadTitleKey|LoadTitleKey SMC]].
 +
 
Takes a u32 ('''keyslot''') and a 16-byte sealed titlekey.
 
Takes a u32 ('''keyslot''') and a 16-byte sealed titlekey.
   Line 405: Line 445:     
== UnwrapAesWrappedTitleKey ==
 
== UnwrapAesWrappedTitleKey ==
 +
Wrapper for [[SMC#UnwrapAesWrappedTitleKey|UnwrapAesWrappedTitleKey SMC]].
 +
 
Takes a 16-byte EKS ('''Encryption Key Source''').
 
Takes a 16-byte EKS ('''Encryption Key Source''').