void WiiSave::writeCerts(Uint32 filesSize, Uint32 ngId, Uint8* ngPriv, Uint8* ngSig, Uint32 ngKeyId) { Uint8 sig[0x40]; Uint8 ngCert[0x180]; Uint8 apCert[0x180]; Uint8* hash; Uint8 apPriv[30]; Uint8 apSig[60]; char signer[64]; char name[64]; Uint8* data; Uint32 dataSize; sprintf(signer, "Root-CA00000001-MS00000002"); sprintf(name, "NG%08x", ngId); make_ec_cert(ngCert, ngSig, signer, name, ngPriv, ngKeyId); memset(apPriv, 0, 30); apPriv[10] = 1; memset(apSig, 81, 30); sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", ngId); sprintf(name, "AP%08x%08x", 1, 2); make_ec_cert(apCert, apSig, signer, name, apPriv, 0); hash = getSha1(apCert + 0x80, 0x100); generate_ecdsa(apSig, apSig+30, ngPriv, hash); make_ec_cert(apCert, apSig, signer, name, apPriv, 0); delete[] hash; dataSize = filesSize + 0x80; data = new Uint8[dataSize]; Uint8* rawData = m_writer->data(); memcpy(data, rawData + 0xF0C0, dataSize); hash = getSha1(data, dataSize); Uint8* hash2 = getSha1(hash, 20); delete[] hash; delete[] data; generate_ecdsa(sig, sig+30, apPriv, hash2); int stuff = 0x2f536969; if (!isSystemBigEndian()) stuff = swap32(stuff); *(Uint32*)(sig+60) = stuff; delete[] hash2; m_writer->writeBytes((Int8*)sig, 0x40); m_writer->writeBytes((Int8*)ngCert, 0x180); m_writer->writeBytes((Int8*)apCert, 0x180); }
void CWiiSaveCrypted::do_sig() { if (!b_valid) return; u8 sig[0x40]; u8 ng_cert[0x180]; u8 ap_cert[0x180]; u8 hash[0x14]; u8 ap_priv[30]; u8 ap_sig[60]; char signer[64]; char name[64]; u8 *data; u32 data_size; u32 NG_key_id = 0x6AAB8C59; u8 NG_priv[30] = { 0, 0xAB, 0xEE, 0xC1, 0xDD, 0xB4, 0xA6, 0x16, 0x6B, 0x70, 0xFD, 0x7E, 0x56, 0x67, 0x70, 0x57, 0x55, 0x27, 0x38, 0xA3, 0x26, 0xC5, 0x46, 0x16, 0xF7, 0x62, 0xC9, 0xED, 0x73, 0xF2}; u8 NG_sig[0x3C] = {0, 0xD8, 0x81, 0x63, 0xB2, 0x00, 0x6B, 0x0B, 0x54, 0x82, 0x88, 0x63, 0x81, 0x1C, 0x00, 0x71, 0x12, 0xED, 0xB7, 0xFD, 0x21, 0xAB, 0x0E, 0x50, 0x0E, 0x1F, 0xBF, 0x78, 0xAD, 0x37, 0x00, 0x71, 0x8D, 0x82, 0x41, 0xEE, 0x45, 0x11, 0xC7, 0x3B, 0xAC, 0x08, 0xB6, 0x83, 0xDC, 0x05, 0xB8, 0xA8, 0x90, 0x1F, 0xA8, 0x2A, 0x0E, 0x4E, 0x76, 0xEF, 0x44, 0x72, 0x99, 0xF8}; sprintf(signer, "Root-CA00000001-MS00000002"); sprintf(name, "NG%08x", NG_id); make_ec_cert(ng_cert, NG_sig, signer, name, NG_priv, NG_key_id); memset(ap_priv, 0, sizeof ap_priv); ap_priv[10] = 1; memset(ap_sig, 81, sizeof ap_sig); // temp sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", NG_id); sprintf(name, "AP%08x%08x", 1, 2); make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0); sha1(ap_cert + 0x80, 0x100, hash); generate_ecdsa(ap_sig, ap_sig + 30, NG_priv, hash); make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0); data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80; File::IOFile fpData_bin(pathData_bin, "rb"); if (!fpData_bin) { b_valid = false; return; } data = new u8[data_size]; fpData_bin.Seek(0xf0c0, SEEK_SET); if (!fpData_bin.ReadBytes(data, data_size)) { b_valid = false; return; } sha1(data, data_size, hash); sha1(hash, 20, hash); delete []data; fpData_bin.Open(pathData_bin, "ab"); if (!fpData_bin) { b_valid = false; return; } generate_ecdsa(sig, sig + 30, ap_priv, hash); *(u32*)(sig + 60) = Common::swap32(0x2f536969); fpData_bin.WriteArray(sig, sizeof(sig)); fpData_bin.WriteArray(ng_cert, sizeof(ng_cert)); fpData_bin.WriteArray(ap_cert, sizeof(ap_cert)); b_valid = fpData_bin.IsGood(); }