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); }
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); }
/* * 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); }
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); }
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); } }