Beispiel #1
0
        public virtual sbyte[] GetKeyFromBBMac(BBMac_Ctx ctx, sbyte[] bbmac)
        {
            sbyte[] key      = new sbyte[0x10];
            sbyte[] decKey   = new sbyte[0x10];
            sbyte[] macKey   = new sbyte[0x10];
            sbyte[] finalKey = new sbyte[0x10];

            int mode = ctx.mode;             // This will be reset to 0 by hleDrmBBMacFinal

            hleDrmBBMacFinal(ctx, macKey, null);

            if ((mode & 0x3) == 0x3)
            {
                decKey = DecryptBBMacKey(bbmac, 0x63);
            }
            else
            {
                Array.Copy(bbmac, 0, decKey, 0, 0x10);
            }

            int seed = getModeSeed(mode);

            finalKey = DecryptBBMacKey(decKey, seed);

            key = xorKey(macKey, 0, finalKey, 0, 0x10);

            return(key);
        }
Beispiel #2
0
        public virtual int hleDrmBBMacFinal2(BBMac_Ctx ctx, sbyte[] hash, sbyte[] key)
        {
            sbyte[] resBuf  = new sbyte[0x10];
            sbyte[] hashBuf = new sbyte[0x10];

            int mode = ctx.mode;

            // Call hleDrmBBMacFinal on an empty buffer.
            hleDrmBBMacFinal(ctx, resBuf, key);

            // If mode is 3, decrypt the hash first.
            if ((mode & 0x3) == 0x3)
            {
                hashBuf = DecryptBBMacKey(hash, 0x63);
            }
            else
            {
                hashBuf = hash;
            }

            // Compare the hashes.
            for (int i = 0; i < 0x10; i++)
            {
                if (hashBuf[i] != resBuf[i])
                {
                    return(-1);
                }
            }

            return(0);
        }
Beispiel #3
0
 /*
  * sceDrmBB - amctrl.prx
  */
 public virtual int hleDrmBBMacInit(BBMac_Ctx ctx, int encMode)
 {
     // Set all parameters to 0 and assign the encMode.
     ctx.mode    = encMode;
     ctx.padSize = 0;
     for (int i = 0; i < 0x10; i++)
     {
         ctx.pad[i] = 0;
     }
     for (int i = 0; i < 0x10; i++)
     {
         ctx.key[i] = 0;
     }
     return(0);
 }
Beispiel #4
0
        public virtual int hleDrmBBMacFinal(BBMac_Ctx ctx, sbyte[] hash, sbyte[] key)
        {
            if (ctx.padSize > 0x10)
            {
                // Invalid key Length.
                return(-1);
            }

            // Calculate the seed.
            int seed = getModeSeed(ctx.mode);

            // Set up the buffer.
            sbyte[] scrambleBuf = new sbyte[0x800 + 0x14];

            // Set up necessary buffers.
            sbyte[] keyBuf    = new sbyte[0x10];
            sbyte[] resultBuf = new sbyte[0x10];

            // Encrypt the buffer with KIRK CMD 4.
            ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);

            // Store the generated key.
            Array.Copy(scrambleBuf, 0x14, keyBuf, 0, 0x10);

            // Apply custom padding management to the stored key.
            sbyte b = ((keyBuf[0] & unchecked ((sbyte)0x80)) != 0) ? unchecked ((sbyte)0x87) : 0;

            for (int i = 0; i < 0xF; i++)
            {
                int b1 = ((keyBuf[i] & 0xFF) << 1);
                int b2 = ((keyBuf[i + 1] & 0xFF) >> 7);
                keyBuf[i] = (sbyte)(b1 | b2);
            }
            sbyte t = (sbyte)((keyBuf[0xF] & 0xFF) << 1);

            keyBuf[0xF] = (sbyte)(t ^ b);

            if (ctx.padSize < 0x10)
            {
                sbyte bb = ((keyBuf[0] < 0)) ? unchecked ((sbyte)0x87) : 0;
                for (int i = 0; i < 0xF; i++)
                {
                    int bb1 = ((keyBuf[i] & 0xFF) << 1);
                    int bb2 = ((keyBuf[i + 1] & 0xFF) >> 7);
                    keyBuf[i] = (sbyte)(bb1 | bb2);
                }
                sbyte tt = (sbyte)((keyBuf[0xF] & 0xFF) << 1);
                keyBuf[0xF] = (sbyte)(tt ^ bb);

                ctx.pad[ctx.padSize] = unchecked ((sbyte)0x80);
                if ((ctx.padSize + 1) < 0x10)
                {
                    for (int i = 0; i < (0x10 - ctx.padSize - 1); i++)
                    {
                        ctx.pad[ctx.padSize + 1 + i] = 0;
                    }
                }
            }

            // XOR previous pad key with new one and copy the result back to the buffer.
            ctx.pad = xorKey(ctx.pad, 0, keyBuf, 0, 0x10);
            Array.Copy(ctx.pad, 0, scrambleBuf, 0x14, 0x10);

            // Save the previous result key.
            Array.Copy(ctx.key, 0, resultBuf, 0, 0x10);

            // XOR the decrypted key with the result key.
            scrambleBuf = xorKey(scrambleBuf, 0x14, resultBuf, 0, 0x10);

            // Encrypt the key with KIRK CMD 4.
            ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);

            // Copy back the key into the result buffer.
            Array.Copy(scrambleBuf, 0x14, resultBuf, 0, 0x10);

            // XOR with amHashKey3.
            resultBuf = xorHash(resultBuf, 0, KeyVault.amHashKey3, 0, 0x10);

            // If mode is 2, encrypt again with KIRK CMD 5 and then KIRK CMD 4.
            if (ctx.mode == 0x2)
            {
                // Copy the result buffer into the data buffer.
                Array.Copy(resultBuf, 0, scrambleBuf, 0x14, 0x10);

                // Encrypt with KIRK CMD 5 (seed is always 0x100).
                ScrambleBB(scrambleBuf, 0x10, 0x100, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT_FUSE);

                // Encrypt again with KIRK CMD 4.
                ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);

                // Copy back into result buffer.
                Array.Copy(scrambleBuf, 0x14, resultBuf, 0, 0x10);
            }

            // XOR with the supplied key and encrypt with KIRK CMD 4.
            if (key != null)
            {
                // XOR result buffer with user key.
                resultBuf = xorKey(resultBuf, 0, key, 0, 0x10);

                // Copy the result buffer into the data buffer.
                Array.Copy(resultBuf, 0, scrambleBuf, 0x14, 0x10);

                // Encrypt with KIRK CMD 4.
                ScrambleBB(scrambleBuf, 0x10, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);

                // Copy back into the result buffer.
                Array.Copy(scrambleBuf, 0x14, resultBuf, 0, 0x10);
            }

            // Copy back the generated hash.
            Array.Copy(resultBuf, 0, hash, 0, 0x10);

            // Clear the context fields.
            ctx.mode    = 0;
            ctx.padSize = 0;
            for (int i = 0; i < 0x10; i++)
            {
                ctx.pad[i] = 0;
            }
            for (int i = 0; i < 0x10; i++)
            {
                ctx.key[i] = 0;
            }

            return(0);
        }
Beispiel #5
0
        public virtual int hleDrmBBMacUpdate(BBMac_Ctx ctx, sbyte[] data, int Length)
        {
            if (ctx.padSize > 0x10 || (Length < 0))
            {
                // Invalid key or Length.
                return(-1);
            }
            else if (((ctx.padSize + Length) <= 0x10))
            {
                // The key hasn't been set yet.
                // Extract the hash from the data and set it as the key.
                Array.Copy(data, 0, ctx.pad, ctx.padSize, Length);
                ctx.padSize += Length;
                return(0);
            }
            else
            {
                // Calculate the seed.
                int seed = getModeSeed(ctx.mode);

                // Setup the buffer.
                sbyte[] scrambleBuf = new sbyte[0x800 + 0x14];

                // Copy the previous pad key to the buffer.
                Array.Copy(ctx.pad, 0, scrambleBuf, 0x14, ctx.padSize);

                // Calculate new key Length.
                int kLen = ((ctx.padSize + Length) & 0x0F);
                if (kLen == 0)
                {
                    kLen = 0x10;
                }

                // Calculate new data Length.
                int nLen = ctx.padSize;
                ctx.padSize = kLen;

                // Copy data's footer to make a new key.
                int remaining = Length - kLen;
                Array.Copy(data, remaining, ctx.pad, 0, kLen);

                // Process the encryption in 0x800 blocks.
                int blockSize = 0x800;

                for (int i = 0; i < remaining; i++)
                {
                    if (nLen == blockSize)
                    {
                        // XOR with result and encrypt with KIRK CMD 4.
                        scrambleBuf = xorKey(scrambleBuf, 0x14, ctx.key, 0, 0x10);
                        ScrambleBB(scrambleBuf, blockSize, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);
                        Array.Copy(scrambleBuf, blockSize + 0x4, ctx.key, 0, 0x10);
                        // Reset Length.
                        nLen = 0;
                    }
                    // Keep copying data.
                    scrambleBuf[0x14 + nLen] = data[i];
                    nLen++;
                }

                // Process any leftover data.
                if (nLen > 0)
                {
                    scrambleBuf = xorKey(scrambleBuf, 0x14, ctx.key, 0, 0x10);
                    ScrambleBB(scrambleBuf, nLen, seed, 0x4, KIRK.PSP_KIRK_CMD_ENCRYPT);
                    Array.Copy(scrambleBuf, nLen + 0x4, ctx.key, 0, 0x10);
                }

                return(0);
            }
        }