public KIRK(sbyte[] seed, int seedLength, int fuseid0, int fuseid1) { // Set up the data for the pseudo random number generator using a // seed set by the user. sbyte[] temp = new sbyte[0x104]; temp[0] = 0; temp[1] = 0; temp[2] = 1; temp[3] = 0; ByteBuffer bTemp = ByteBuffer.wrap(temp); ByteBuffer bPRNG = ByteBuffer.wrap(prng_data); // Random data to act as a key. sbyte[] key = new sbyte[] { (sbyte)0x07, unchecked ((sbyte)0xAB), unchecked ((sbyte)0xEF), unchecked ((sbyte)0xF8), unchecked ((sbyte)0x96), unchecked ((sbyte)0x8C), unchecked ((sbyte)0xF3), unchecked ((sbyte)0xD6), (sbyte)0x14, unchecked ((sbyte)0xE0), unchecked ((sbyte)0xEB), unchecked ((sbyte)0xB2), unchecked ((sbyte)0x9D), unchecked ((sbyte)0x8B), (sbyte)0x4E, (sbyte)0x74 }; // Direct call to get the system time. int systime = (int)DateTimeHelper.CurrentUnixTimeMillis(); // Generate a SHA-1 hash for the PRNG. if (seedLength > 0) { sbyte[] seedBuf = new sbyte[seedLength + 4]; ByteBuffer bSeedBuf = ByteBuffer.wrap(seedBuf); SHA1_Header seedHeader = new SHA1_Header(this, bSeedBuf); bSeedBuf.rewind(); seedHeader.dataSize = seedLength; executeKIRKCmd11(bPRNG, bSeedBuf, seedLength + 4); } // Use the system time for randomness. Array.Copy(prng_data, 0, temp, 4, 0x14); temp[0x18] = unchecked ((sbyte)(systime & 0xFF)); temp[0x19] = unchecked ((sbyte)((systime >> 8) & 0xFF)); temp[0x1A] = unchecked ((sbyte)((systime >> 16) & 0xFF)); temp[0x1B] = unchecked ((sbyte)((systime >> 24) & 0xFF)); // Set the sealed override PRNG number. Array.Copy(key, 0, temp, 0x1C, 0x10); bPRNG.clear(); executeKIRKCmd11(bPRNG, bTemp, 0x104); fuseID0 = fuseid0; fuseID1 = fuseid1; }
// Generate SHA1 hash. private int executeKIRKCmd11(ByteBuffer @out, ByteBuffer @in, int size) { // Return an error if the crypto engine hasn't been initialized. if (!CryptoEngine.CryptoEngineStatus) { return(PSP_KIRK_NOT_INIT); } int outPosition = @out.position(); SHA1_Header header = new SHA1_Header(this, @in); SHA1 sha1 = new SHA1(); size = (size < header.dataSize) ? size : header.dataSize; header.readData(@in, size); @out.position(outPosition); @out.put(sha1.doSHA1(header.data, size)); @in.clear(); return(0); }