int SavedataParam::BuildHash(unsigned char *output, unsigned char *data, unsigned int len, unsigned int alignedLen, int mode, unsigned char *cryptkey) { pspChnnlsvContext1 ctx1; /* Set up buffers */ memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); memset(output, 0, 0x10); memset(data + len, 0, alignedLen - len); /* Perform the magic */ if (sceSdSetIndex_(ctx1, mode & 0xFF) < 0) return -1; if (sceSdRemoveValue_(ctx1, data, alignedLen) < 0) return -2; if (sceSdGetLastIndex_(ctx1, output, cryptkey) < 0) { // Got here since Kirk CMD5 missing, return random value; memset(output,0x1,0x10); return 0; } /* All done. */ return 0; }
int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) { pspChnnlsvContext1 ctx; Memory::ReadStruct(addressCtx, &ctx); //Read in the struct from addressCtx into ctx int res = sceSdGetLastIndex_(ctx, Memory::GetPointer(addressHash), Memory::GetPointer(addressKey)); Memory::WriteStruct(addressCtx, &ctx); //Write back the struct from ctx to addressCtx return res; }
int SavedataParam::EncryptData(unsigned int mode, unsigned char *data, int *dataLen, int *alignedLen, unsigned char *hash, unsigned char *cryptkey) { pspChnnlsvContext1 ctx1; pspChnnlsvContext2 ctx2; /* Make room for the IV in front of the data. */ memmove(data + 0x10, data, *alignedLen); /* Set up buffers */ memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); memset(&ctx2, 0, sizeof(pspChnnlsvContext2)); memset(hash, 0, 0x10); memset(data, 0, 0x10); /* Build the 0x10-byte IV and setup encryption */ if (sceSdCreateList_(ctx2, mode, 1, data, cryptkey) < 0) return -1; if (sceSdSetIndex_(ctx1, mode) < 0) return -2; if (sceSdRemoveValue_(ctx1, data, 0x10) < 0) return -3; if (sceSdSetMember_(ctx2, data + 0x10, *alignedLen) < 0) return -4; /* Clear any extra bytes left from the previous steps */ memset(data + 0x10 + *dataLen, 0, *alignedLen - *dataLen); /* Encrypt the data */ if (sceSdRemoveValue_(ctx1, data + 0x10, *alignedLen) < 0) return -5; /* Verify encryption */ if (sceChnnlsv_21BE78B4_(ctx2) < 0) return -6; /* Build the file hash from this PSP */ if (sceSdGetLastIndex_(ctx1, hash, cryptkey) < 0) return -7; /* Adjust sizes to account for IV */ *alignedLen += 0x10; *dataLen += 0x10; /* All done */ return 0; }