Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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");
            }
        }