Advertising (This ad goes away for registered users. You can Login or Register)

PS3 packages and how it leads to PSP signing

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
chapix
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Post by chapix »

After a bit more searching i found that my block differs from original one of 0xF bytes, is that normal ?
The last 0xf bytes is CMACHASH.
Advertising
The Lemon Man
Posts: 7
Joined: Sun Jan 16, 2011 1:35 pm

Re: PS3 packages and how it leads to PSP signing

Post by The Lemon Man »

chapix wrote:
After a bit more searching i found that my block differs from original one of 0xF bytes, is that normal ?
The last 0xf bytes is CMACHASH.
Hash of what ?
Advertising
chapix
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Post by chapix »

According KGSWS is Hash of Header.
The Lemon Man
Posts: 7
Joined: Sun Jan 16, 2011 1:35 pm

Re: PS3 packages and how it leads to PSP signing

Post by The Lemon Man »

chapix wrote:According KGSWS is Hash of Header.
So it's a copy of the header hash from the cmd1 header ?
chapix
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Post by chapix »

i don't know how Kgsws generate these 0x7 bytes.
n00b81
HBL Collaborator
Posts: 31
Joined: Sat Oct 09, 2010 6:39 pm

Re: PS3 packages and how it leads to PSP signing

Post by n00b81 »

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
Hykem
Guru
Posts: 75
Joined: Sat Jan 15, 2011 8:11 pm

Re: PS3 packages and how it leads to PSP signing

Post by Hykem »

hitchhikr wrote:
is the decryptMode supposed to match the last param passed to sceUtilsBufferCopyWithRange, or is it something else?
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).
Ah, thanks for the clarification. That value does commonly match the decrypted module's mod_attr field's lower bits (often 1, 4, 9).

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.
Proxima
Guru
Posts: 47
Joined: Mon Jan 03, 2011 2:38 pm

Re: PS3 packages and how it leads to PSP signing

Post by Proxima »

Here's some code to support the CMAC collision forging. In crypto.c, add the following function:

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];
    }
}
In kirk-engine.c add the following function:

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
}
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.
Proxima
Guru
Posts: 47
Joined: Mon Jan 03, 2011 2:38 pm

Re: PS3 packages and how it leads to PSP signing

Post by Proxima »

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;
}
Draan
Posts: 72
Joined: Tue Dec 21, 2010 9:49 pm

Re: PS3 packages and how it leads to PSP signing

Post by Draan »

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.
WTF? First thing, this coded by myself is already in code. Second, you're decrypting decrypted keys (???), third, you're not calculating hashes.

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? ;)
Post Reply

Return to “Programming and Security”