Cave StoryRandom Homebrew: Cave Story
Probably the most famous platform freeware game, cave story is the result of 5 years of work by an i [...]
Friends: Coding 'n Cracking - Nymphaea - PS3 Forum - darkforestgroup - daxhordes.org - Tgames - coldbird - gopsp.it - pspstation.org - prometheus - hgoel.info - MakeSmartTV - ps vita

PS3 packages and how it leads to PSP signing

Forum rules
Any post not directly related to programming will be moderated.
Do not request people to code something for you.
Avoid posting messages that do not bring anything to the conversation. We want the threads in this subforum to stay focused.

Re: PS3 packages and how it leads to PSP signing

Postby chapix » Sun Jan 16, 2011 3:29 pm

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.
chapix
 
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Postby The Lemon Man » Sun Jan 16, 2011 3:57 pm

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 ?
The Lemon Man
 
Posts: 10
Joined: Sun Jan 16, 2011 1:35 pm

Re: PS3 packages and how it leads to PSP signing

Postby chapix » Sun Jan 16, 2011 4:02 pm

According KGSWS is Hash of Header.
chapix
 
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Postby The Lemon Man » Sun Jan 16, 2011 4:05 pm

chapix wrote:According KGSWS is Hash of Header.


So it's a copy of the header hash from the cmd1 header ?
The Lemon Man
 
Posts: 10
Joined: Sun Jan 16, 2011 1:35 pm

Re: PS3 packages and how it leads to PSP signing

Postby chapix » Sun Jan 16, 2011 4:50 pm

i don't know how Kgsws generate these 0x7 bytes.
chapix
 
Posts: 6
Joined: Sat Jan 15, 2011 7:26 pm

Re: PS3 packages and how it leads to PSP signing

Postby n00b81 » Sun Jan 16, 2011 5:36 pm

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
HBL Collaborator
 
Posts: 12
Joined: Sat Oct 09, 2010 6:39 pm

Re: PS3 packages and how it leads to PSP signing

Postby Hykem » Sun Jan 16, 2011 6:00 pm

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

Re: PS3 packages and how it leads to PSP signing

Postby Proxima » Sun Jan 16, 2011 7:53 pm

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
 
Posts: 20
Joined: Mon Jan 03, 2011 2:38 pm

Re: PS3 packages and how it leads to PSP signing

Postby Proxima » Sun Jan 16, 2011 8:27 pm

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

Re: PS3 packages and how it leads to PSP signing

Postby Draan » Sun Jan 16, 2011 8:44 pm

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

PreviousNext

Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests