The last 0xf bytes is CMACHASH.After a bit more searching i found that my block differs from original one of 0xF bytes, is that normal ?
PS3 packages and how it leads to PSP signing
Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Forum rule Nº 15 is strictly enforced in this subforum.
Re: PS3 packages and how it leads to PSP signing
Advertising
-
- Posts: 7
- Joined: Sun Jan 16, 2011 1:35 pm
Re: PS3 packages and how it leads to PSP signing
Hash of what ?chapix wrote:The last 0xf bytes is CMACHASH.After a bit more searching i found that my block differs from original one of 0xF bytes, is that normal ?
Advertising
Re: PS3 packages and how it leads to PSP signing
According KGSWS is Hash of Header.
-
- Posts: 7
- Joined: Sun Jan 16, 2011 1:35 pm
Re: PS3 packages and how it leads to PSP signing
So it's a copy of the header hash from the cmd1 header ?chapix wrote:According KGSWS is Hash of Header.
Re: PS3 packages and how it leads to PSP signing
i don't know how Kgsws generate these 0x7 bytes.
Re: PS3 packages and how it leads to PSP signing
Just wanted to add that I tested the reflection homebrew on my PSP 3000 6.35, and it worked fine. Nice job so far, kgsws and others
n00b81
n00b81
Re: PS3 packages and how it leads to PSP signing
Ah, thanks for the clarification. That value does commonly match the decrypted module's mod_attr field's lower bits (often 1, 4, 9).hitchhikr wrote:That's something else entirely, it's used to determine which file type and where if it can be run depending on where it's located (it's also linked to the mod_attribute field).is the decryptMode supposed to match the last param passed to sceUtilsBufferCopyWithRange, or is it something else?
By the way, I've tried messing around with several homebrew apps patched with the same UCES00206 ~PSP header (as figured by kgsws), and so far I've managed to run most of the available demos (PSPSDK and a couple of custom made ones), including one GE draw list sample with about 615kb of size on a PSP 3000 with OFW 6.35. All I did was checking it's compiled ELF size and the resulting encrypted PSP's size and replace these values in the UCES00206 ~PSP header struct (also has to be replaced in comp_size) before repacking it.
I'm wondering if it was just plain coincidence or if these values alone can actually influence the calls to the crypto engine.
Re: PS3 packages and how it leads to PSP signing
Here's some code to support the CMAC collision forging. In crypto.c, add the following function:
In kirk-engine.c add the following function:
Then if you call the kirk_forge function with the buffer with the modified data, it will correct the last row to match the CMAC in the header.
Code: Select all
void AES_CMAC_forge (AES_ctx *ctx, unsigned char *input, int length, unsigned char * forge )
{
unsigned char X[16],Y[16], M_last[16], padded[16];
unsigned char K1[16], K2[16];
int n, i, flag;
generate_subkey(ctx,K1,K2);
n = (length+15) / 16; /* n is number of rounds */
if ( n == 0 )
{
n = 1;
flag = 0;
} else {
if ( (length%16) == 0 ) { /* last block is a complete block */
flag = 1;
} else { /* last block is not complete block */
flag = 0;
}
}
if ( flag ) { /* last block is complete block */
xor_128(&input[16*(n-1)],K1,M_last);
} else {
padding(&input[16*(n-1)],padded,length%16);
xor_128(padded,K2,M_last);
}
for ( i=0; i<16; i++ ) X[i] = 0;
for ( i=0; i<n-1; i++ )
{
xor_128(X,&input[16*i],Y); /* Y := Mi (+) X */
AES_encrypt(ctx, Y, X); /* X := AES-128(KEY, Y); */
}
xor_128(X,M_last,Y);
AES_decrypt(ctx, forge, X);
//printf("Pre-crypt value: "); for(i=0;i<0x10;i++) printf("%02x", X[i]); printf("\n");
xor_128(X,Y,forge);
xor_128(forge,&input[16*(n-1)],Y);
//AES_encrypt(Y, X, &aes);
//Update original input file so it produces the correct CMAC
for ( i=0; i<16; i++ ) {
input[(16*(n-1))+i]= Y[i];
}
}
Code: Select all
int kirk_forge(u8* inbuff, int insize)
{
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
AES_ctx cmac_key;
u8 cmac_header_hash[16];
u8 cmac_data_hash[16];
int chk_size,i;
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
if(!(header->mode == KIRK_MODE_CMD1 || header->mode == KIRK_MODE_CMD2 || header->mode == KIRK_MODE_CMD3)) return KIRK_INVALID_MODE;
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
if(header->mode == KIRK_MODE_CMD1){
header_keys keys; //0-15 AES key, 16-31 CMAC key
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
AES_set_key(&cmac_key, keys.CMAC, 128);
AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
if(memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) return KIRK_HEADER_HASH_INVALID;
//Make sure data is 16 aligned
chk_size = header->data_size;
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
AES_CMAC(&cmac_key, inbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
if(memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0) {
printf("data hash invalid, correcting...\n");
} else {
printf("data hash is already valid!\n");
return 100;
}
// Forge collision for data hash
memcpy(cmac_data_hash,header->CMAC_data_hash,0x10);
AES_CMAC_forge(&cmac_key, inbuff+0x60, 0x30+ chk_size + header->data_offset, cmac_data_hash);
//printf("Last row in bad file should be :\n"); for(i=0;i<0x10;i++) printf("%02x", cmac_data_hash[i]);
//printf("\n\n");
return KIRK_OPERATION_SUCCESS;
}
return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
}
Re: PS3 packages and how it leads to PSP signing
One more function for kirk-engine.c. It's the encryption version of CMD1. Used to encrypt a plaintext ELF with the header info. Call this just before you call kirk_forge. I called it CMD0, but rename it as you like.
Code: Select all
int kirk_CMD0(u8* outbuff, u8* inbuff, int size)
{
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
header_keys keys;
AES_ctx k1;
int ret;
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
//0-15 AES key, 16-31 CMAC key
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 16*2); //decrypt AES & CMAC key to temp buffer
//ret = kirk_CMD10(inbuff, size);
//if(ret != KIRK_OPERATION_SUCCESS) return ret;
AES_set_key(&k1, keys.AES, 128);
AES_cbc_encrypt(&k1, inbuff+sizeof(struct CMD1_HEADER)+header->data_offset, outbuff+sizeof(struct CMD1_HEADER)+header->data_offset, header->data_size);
memcpy(outbuff,inbuff,sizeof(struct CMD1_HEADER)+header->data_offset);
return KIRK_OPERATION_SUCCESS;
}
Re: PS3 packages and how it leads to PSP signing
WTF? First thing, this coded by myself is already in code. Second, you're decrypting decrypted keys (???), third, you're not calculating hashes.Proxima wrote:One more function for kirk-engine.c. It's the encryption version of CMD1. Used to encrypt a plaintext ELF with the header info. Call this just before you call kirk_forge. I called it CMD0, but rename it as you like.
On the other hand, kirk_forge can be usefull, i'll think about adding it.
EDIT: Hmm...I see. You want to "join" header from orginal PRX with your own data...Well, it cannot be CMD0, because we would have a conflict. Maybe new "HAX" section of kirk-engine?