void file_copy_append(Stream nand, Stream writer, DSi_CTR ctx, int start_addr, int end_addr, ProgressBar nandprog) { const int buf_size = 0x100000; byte[] buf = new byte[buf_size]; nand.Seek(start_addr, SeekOrigin.Begin); for (int i = start_addr; i < end_addr; i += buf_size) { int cur_size = (end_addr - i) >= buf_size ? buf_size : end_addr - i; if (ctx != null) { buf = ctx.Crypt_all(nand, cur_size); } else { nand.Read(buf, 0, cur_size); } writer.Write(buf, 0, cur_size); if (nandprog != null) { nandprog.Value = Convert.ToInt32(100.0 * (i - start_addr) / (end_addr - start_addr)); } } if (nandprog != null) { nandprog.Value = 100; } }
public byte[] Decrypt(byte[] input, out byte[] paramac) { byte[] block = new byte[16]; byte[] tblock = new byte[16]; byte[] tctr = new byte[16]; paramac = new byte[16]; int size = input.Length - 0x20; byte[] outblock = new byte[size]; int i = 0; Array.Copy(input, i, tblock, 0, 16); while (size > 16) { byte[] oblock = Decrypt_Block(tblock, ref paramac); Array.Copy(oblock, 0, outblock, i, 16); size -= 16; i += 16; Array.Copy(input, i, tblock, 0, 16); } DSi_CTR cryptoctx = new DSi_CTR() { _Key = Key, _Ctr = ctr.Clone() as byte[] }; block = cryptoctx.Crypt(block); Array.Copy(input, i, block, 0, size); block = Decrypt_Block(block, ref paramac); Array.Copy(block, 0, outblock, i, size); return(outblock); }
public byte[] Decrypt_Block(byte[] input, ref byte[] paramac) { DSi_CTR cryptoctx = new DSi_CTR() { _Key = Key, _Ctr = ctr }; byte[] output = cryptoctx.Crypt(input); for (int i = 0; i < 16; i++) { mac[i] ^= output[15 - i]; } AesManaged aesAlg = new AesManaged { Mode = CipherMode.ECB }; ICryptoTransform encryptor = aesAlg.CreateEncryptor(Key, null); mac = encryptor.TransformFinalBlock(mac, 0, 16); for (int i = 0; i < 16; i++) { paramac[i] = Convert.ToByte(mac[15 - i] ^ S0[i]); } return(output); }
public DSi_CCM(byte[] key, int maclength, int payloadlength, int assoclength, byte[] nonce) { this.Key = key; this.maclen = maclength; maclength = (maclength - 2) / 2; payloadlength = (payloadlength + 15) & ~15; mac[0] = Convert.ToByte((maclength << 3) | 2); if (assoclength != 0) { mac[0] |= (1 << 6); } for (int i = 0; i < 12; i++) { mac[1 + i] = nonce[11 - i]; } mac[13] = Convert.ToByte(payloadlength >> 16); mac[14] = Convert.ToByte(payloadlength >> 8); mac[15] = Convert.ToByte((payloadlength >> 0) % 256); AesManaged aesAlg = new AesManaged { Mode = CipherMode.ECB }; ICryptoTransform encryptor = aesAlg.CreateEncryptor(key, null); mac = encryptor.TransformFinalBlock(mac, 0, 16); ctr[0] = 2; for (int i = 0; i < 12; i++) { ctr[1 + i] = nonce[11 - i]; } ctr[13] = 0; ctr[14] = 0; ctr[15] = 0; DSi_CTR cryptoctx = new DSi_CTR() { _Key = key, _Ctr = ctr }; S0 = cryptoctx.Crypt(null); }
public byte[] Decrypt(byte[] buffer, byte[] metablock) { byte[] ctr = new byte[16]; byte[] dnonce = new byte[12]; byte[] scratchpad = new byte[16]; byte[] chkmac = new byte[16]; byte[] genmac = new byte[16]; byte[] blockcrypt = new byte[16]; int chksize; Array.Copy(metablock, chkmac, 16); Array.Copy(metablock, 16, ctr, 0, 16); Array.Copy(metablock, 16, blockcrypt, 0, 16); ctr[0] = 0; ctr[13] = 0; ctr[14] = 0; ctr[15] = 0; DSi_CTR cryptoctx = new DSi_CTR() { Key = Key, Ctr = ctr }; scratchpad = cryptoctx.Crypt(blockcrypt); chksize = (scratchpad[13] << 16) | (scratchpad[14] << 8) | (scratchpad[15] << 0); if (scratchpad[0] != 0x3A || chksize != buffer.Length - 0x20) { return(null); } Array.Copy(metablock, 17, dnonce, 0, 12); DSi_CCM crypt = new DSi_CCM(Key, 16, buffer.Length - 0x20, 0, dnonce); buffer = crypt.Decrypt(buffer, out genmac); return(buffer); }
public void cryptNAND(Stream nand, Stream nandwrite, ProgressBar nandprog) { byte[] emmc_keyX = new byte[16]; byte[] emmc_normalkey = new byte[16]; byte[] emmc_cid_hash = new byte[20]; byte[] base_ctr = new byte[16]; SHA1 sha = new SHA1CryptoServiceProvider(); emmc_cid_hash = sha.ComputeHash(CID); Array.Copy(emmc_cid_hash, base_ctr, 16); Array.Reverse(ConsoleID); Array.Copy(ConsoleID, emmc_keyX, 4); Array.Copy(BitConverter.GetBytes(BitConverter.ToUInt32(ConsoleID, 0) ^ 0x24EE6906), 0, emmc_keyX, 4, 4); Array.Copy(BitConverter.GetBytes(BitConverter.ToUInt32(ConsoleID, 4) ^ 0xE65B601D), 0, emmc_keyX, 8, 4); Array.Copy(ConsoleID, 4, emmc_keyX, 12, 4); KeyCrypto.F_XY(out emmc_normalkey, ref emmc_keyX, ref emmc_keyY); DSi_CTR ctx = new DSi_CTR() { Ctr = base_ctr.Clone() as byte[], Key = emmc_normalkey }; byte[] mbr = new byte[0x200]; bool encrypted; nand.Read(mbr, 0, 0x200); if (mbr[0x1FE] != 0x55 || mbr[0x1FF] != 0xAA) { nand.Seek(0, SeekOrigin.Begin); mbr = ctx.Crypt_all(nand, 0x200); if (mbr[0x1FE] != 0x55 || mbr[0x1FF] != 0xAA) { MessageBox.Show("Invalid NAND"); return; } encrypted = true; } else { encrypted = false; } ctx.Ctr = base_ctr.Clone() as byte[]; { file_copy_append(nand, nandwrite, ctx, 0, 0x200, nandprog); file_copy_append(nand, nandwrite, null, 0x200, 0x10EE00, null); ctx.Ctr = base_ctr.Clone() as byte[]; ctx.add_ctr((0x10EE00 / 0x10)); file_copy_append(nand, nandwrite, ctx, 0x10EE00, 0x0CF00000, nandprog); file_copy_append(nand, nandwrite, null, 0x0CF00000, 0x0CF09A00, null); ctx.Ctr = base_ctr.Clone() as byte[]; ctx.add_ctr((0x0CF09A00 / 0x10)); file_copy_append(nand, nandwrite, ctx, 0x0CF09A00, 0x0EFC0000, nandprog); file_copy_append(nand, nandwrite, null, 0x0EFC0000, 0x0F000000, null); } if (encrypted) { MessageBox.Show("Successfully decrypted NAND"); } else { MessageBox.Show("Successfully encrypted NAND"); } }