logo upd; TitleKEKs added

master
Dmitry Isaenko 2019-05-22 19:13:51 +03:00
parent f7777012b9
commit a6b46660d8
6 changed files with 80 additions and 50 deletions

View File

@ -50,6 +50,9 @@ public class AppPreferences {
public String getSystemKey(int number){ return preferences.get("key_area_key_system_0"+number, "");}
public void setSystemKey(int number, String key){ preferences.put("key_area_key_system_0"+number, key); }
public String getTitleKek(int number){ return preferences.get("titlekek_"+number, "");}
public void setTitleKek(int number, String key){ preferences.put("titlekek_"+number, key); }
public int getTitleKeysCount(){ // TODO: do the same for other multi-keys and single

View File

@ -76,11 +76,11 @@ public class NCAController implements TabController {
this.selectedFile = file;
HashMap<String, String> keysMap = new HashMap<>();
keysMap.put("header_key", AppPreferences.getInstance().getHeaderKey());
for (int i = 0; i < 8; i++){
for (int i = 0; i < 8; i++){ // TODO: FIX!!!!!!!!! URGENT!
keysMap.put("key_area_key_application_0"+i, AppPreferences.getInstance().getApplicationKey(i));
keysMap.put("key_area_key_ocean_0"+i, AppPreferences.getInstance().getOceanKey(i));
keysMap.put("key_area_key_system_0"+i, AppPreferences.getInstance().getSystemKey(i));
// TODO: Add titlekeys
keysMap.put("titlekek_0"+i, AppPreferences.getInstance().getTitleKek(i));
}
for (int i = 0; i < AppPreferences.getInstance().getTitleKeysCount(); i++){
String[] pair = AppPreferences.getInstance().getTitleKeyPair(i);

View File

@ -25,6 +25,7 @@ public class SettingsController implements Initializable {
ListSelectorKAEKAppController,
ListSelectorKAEKOceanController,
ListSelectorKAEKSysController,
ListSelectorTitleKeksController,
ListSelectorTitleKeysController;
@FXML
@ -37,6 +38,7 @@ public class SettingsController implements Initializable {
ListSelectorKAEKAppController.initSelector(32, "key_area_key_application_");
ListSelectorKAEKOceanController.initSelector(32, "key_area_key_ocean_");
ListSelectorKAEKSysController.initSelector(32, "key_area_key_system_");
ListSelectorTitleKeksController.initSelector(32, "titlekek_");
ListSelectorTitleKeysController.initSelector(32, null); // 32 required
LinkedHashMap<String, String> preparedPairsMapInit = new LinkedHashMap<>();
@ -57,6 +59,14 @@ public class SettingsController implements Initializable {
}
ListSelectorKAEKOceanController.setList(preparedPairsMapInit);
preparedPairsMapInit.clear();
cnt = 0;
while (!(kaekApp = AppPreferences.getInstance().getTitleKek(cnt)).isEmpty()){
preparedPairsMapInit.put("titlekek_"+String.format("%02d", cnt), kaekApp);
cnt++;
}
ListSelectorTitleKeksController.setList(preparedPairsMapInit);
preparedPairsMapInit.clear();
cnt = 0;
while (!(kaekApp = AppPreferences.getInstance().getSystemKey(cnt)).isEmpty()){
@ -129,6 +139,14 @@ public class SettingsController implements Initializable {
counter++;
}
ListSelectorKAEKSysController.setList(kaekSingle);
kaekSingle.clear();
counter = 0;
while ((keyParsed = fileMap.get("titlekek_"+String.format("%02d", counter))) != null){
kaekSingle.put("titlekek_"+String.format("%02d", counter), keyParsed);
counter++;
}
ListSelectorTitleKeksController.setList(kaekSingle);
}
catch (IOException ioe){
ioe.printStackTrace();
@ -198,6 +216,12 @@ public class SettingsController implements Initializable {
AppPreferences.getInstance().setSystemKey(i, kaekSysKeySet[i].split("\\s=\\s", 2)[1]);
}
String[] titleKekSet = ListSelectorTitleKeksController.getList();
if (titleKekSet != null){
for (int i = 0; i < titleKekSet.length; i++)
AppPreferences.getInstance().setTitleKek(i, titleKekSet[i].split("\\s=\\s", 2)[1]);
}
String[] titleKeysSet = ListSelectorTitleKeysController.getList();
if (titleKeysSet != null){
AppPreferences.getInstance().setTitleKeysCount(titleKeysSet.length);

View File

@ -1,5 +1,6 @@
package konogonka.Tools.NCA;
import konogonka.LoperConverter;
import konogonka.Tools.NCA.NCASectionTableBlock.NCASectionBlock;
import konogonka.xtsaes.XTSAESCipher;
import org.bouncycastle.crypto.params.KeyParameter;
@ -11,6 +12,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import static konogonka.LoperConverter.byteArrToHexString;
import static konogonka.LoperConverter.getLElong;
// TODO: check file size
@ -32,6 +34,8 @@ public class NCAProvider {
private byte cryptoType2; // keyblob index. Considering as number within application/ocean/system
private byte[] rightsId;
private byte cryptoTypeReal;
private byte[] sha256hash0;
private byte[] sha256hash1;
private byte[] sha256hash2;
@ -152,32 +156,28 @@ public class NCAProvider {
encryptedKey2 = Arrays.copyOfRange(encryptedKeysArea, 0x20, 0x30);
encryptedKey3 = Arrays.copyOfRange(encryptedKeysArea, 0x30, 0x40);
// Calculate real Crypto Type
if (cryptoType1 < cryptoType2)
cryptoTypeReal = cryptoType2;
else
cryptoTypeReal = cryptoType1;
if (cryptoTypeReal > 0) // TODO: CLARIFY WHY THEH FUCK IS IT FAIR????
cryptoTypeReal -= 1;
//todo: if nca3 proceed
// If no rights ID (ticket?) exists
// Decrypt keys if encrypted
if (Arrays.equals(rightsId, new byte[0x10])) {
byte realCryptoType;
if (cryptoType1 < cryptoType2)
realCryptoType = cryptoType2;
else
realCryptoType = cryptoType1;
if (realCryptoType > 0) // TODO: CLARIFY WHY THEH FUCK IS IT FAIR????
realCryptoType -= 1;
String keyAreaKey;
switch (keyIndex){
case 0:
keyAreaKey = keys.get("key_area_key_application_0"+realCryptoType);
System.out.println("Using key_area_key_application_0"+realCryptoType);
keyAreaKey = keys.get("key_area_key_application_"+String.format("%02d", cryptoTypeReal));
break;
case 1:
keyAreaKey = keys.get("key_area_key_ocean_0"+realCryptoType);
System.out.println("Using key_area_key_ocean_0"+realCryptoType);
keyAreaKey = keys.get("key_area_key_ocean_"+String.format("%02d", cryptoTypeReal));
break;
case 2:
keyAreaKey = keys.get("key_area_key_system_0"+realCryptoType);
System.out.println("Using key_area_key_system_0"+realCryptoType);
keyAreaKey = keys.get("key_area_key_system_"+String.format("%02d", cryptoTypeReal));
break;
default:
keyAreaKey = null;
@ -193,11 +193,6 @@ public class NCAProvider {
decryptedKey3 = cipher.doFinal(encryptedKey3);
}
}
else {
// TODO
}
tableEntry0 = new NCAHeaderTableEntry(tableBytes);
tableEntry1 = new NCAHeaderTableEntry(Arrays.copyOfRange(tableBytes, 0x10, 0x20));
@ -253,33 +248,39 @@ public class NCAProvider {
* @param sectionNumber should be 1-4
* */
public NCAContentPFS0 getNCAContentPFS0(int sectionNumber){
// TODO: provide titleKey if needed
byte[] key;
switch (sectionNumber){
// If empty Rights ID
if (Arrays.equals(rightsId, new byte[0x10])) {
key = decryptedKey2; // TODO: Just remember this dumb hach
}
else {
byte[] rightsIDkey = hexStrToByteArray(keys.get(byteArrToHexString(rightsId)));
try {
SecretKeySpec skSpec = new SecretKeySpec(
hexStrToByteArray(keys.get("titlekek_"+String.format("%02d", cryptoTypeReal))
), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skSpec);
key = cipher.doFinal(rightsIDkey);
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
switch (sectionNumber) {
case 0:
return new NCAContentPFS0(file, offset, sectionBlock0, tableEntry0, decryptedKey2); // TODO: remove decryptedKey2
return new NCAContentPFS0(file, offset, sectionBlock0, tableEntry0, key); // TODO: remove decryptedKey2
case 1:
return new NCAContentPFS0(file, offset, sectionBlock1, tableEntry1, decryptedKey2);
return new NCAContentPFS0(file, offset, sectionBlock1, tableEntry1, key);
case 2:
return new NCAContentPFS0(file, offset, sectionBlock2, tableEntry2, decryptedKey2);
return new NCAContentPFS0(file, offset, sectionBlock2, tableEntry2, key);
case 3:
return new NCAContentPFS0(file, offset, sectionBlock3, tableEntry3, decryptedKey2);
return new NCAContentPFS0(file, offset, sectionBlock3, tableEntry3, key);
default:
return null;
}
}
}
// 0 OR 2 crypto type
// 0,1,2 kaek index
//settings.keyset.key_area_keys[ctx->crypto_type][ctx->header.kaek_ind]
/*
0x207 =
0: key_area_key_application_ 0x206 range:[0-6]; usually used 0 or 2
1: key_area_key_ocean [0-6]
2: key_area_key_system [0-6]
if(ncahdr_x206 < ncahdr_x220){ret = ncahdr_x220; } else { ret = ncahdr_x206; } return ret;
ret > 0? ret--
*/
}

View File

@ -48,15 +48,18 @@
<Label disable="true" text="Length should be 64 symbols" wrapText="true" />
<Pane VBox.vgrow="ALWAYS" />
<Separator prefWidth="200.0" />
<Label text="Label" />
<Label text="Key area key &quot;Application&quot;" />
<fx:include fx:id="ListSelectorKAEKApp" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
<Separator prefWidth="200.0" />
<Label text="Label" />
<Label text="Key area key &quot;Ocean&quot;" />
<fx:include fx:id="ListSelectorKAEKOcean" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
<Separator prefWidth="200.0" />
<Label text="Label" />
<Label text="Key area key &quot;System&quot;" />
<fx:include fx:id="ListSelectorKAEKSys" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
<Separator prefWidth="200.0" />
<Label text="Title KEKs" />
<fx:include fx:id="ListSelectorTitleKeks" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
<Separator prefWidth="200.0" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
@ -108,8 +111,7 @@
</TabPane>
<ButtonBar>
<buttons>
<Button fx:id="okBtn" mnemonicParsing="false" text="Ok" />
<Button fx:id="okBtn" mnemonicParsing="false" text="Ok" />
<Button fx:id="cancelBtn" mnemonicParsing="false" text="Cancel" />
</buttons>
<padding>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 24 KiB