Ejemplo n.º 1
0
int sce_decrypt_header(u8 *ptr, struct keylist *klist)
{
	u32 meta_offset;
	u32 meta_len;
	u64 header_len;
	u32 i, j;
	u8 tmp[0x40];
	int success = 0;

	meta_offset = be32(ptr + 0x0c);
	header_len  = be64(ptr + 0x10);

	for (i = 0; i < klist->n; i++) {
		aes256cbc(klist->keys[i].key,
			  klist->keys[i].iv,
			  ptr + meta_offset + 0x20,
			  0x40,
			  tmp); 

		success = 1;
		for (j = 0x10; j < (0x10 + 0x10); j++)
			if (tmp[j] != 0)
				success = 0;
	
		for (j = 0x30; j < (0x30 + 0x10); j++)
			if (tmp[j] != 0)
			       success = 0;

		if (success == 1) {
			memcpy(ptr + meta_offset + 0x20, tmp, 0x40);
			break;
		}
	}

	if (success != 1)
		return -1;

	printf(" Metadata key id: %s\n", klist->keys[i].id);

	memcpy(tmp, ptr + meta_offset + 0x40, 0x10);
	aes128ctr(ptr + meta_offset + 0x20,
		  tmp,
		  ptr + meta_offset + 0x60,
		  0x20,
		  ptr + meta_offset + 0x60);

	meta_len = header_len - meta_offset;

	aes128ctr(ptr + meta_offset + 0x20,
		  tmp,
		  ptr + meta_offset + 0x80,
		  meta_len - 0x80,
		  ptr + meta_offset + 0x80);

	return i;
}
Ejemplo n.º 2
0
static int
decrypt_metadata(uint8_t *metadata, uint32_t metadata_size,
                 struct keylist *klist)
{
    uint32_t i;
    METADATA_INFO metadata_info;
    uint8_t zero[16] = {0};

    for (i = 0; i < klist->n; i++) {
        aes256cbc(klist->keys[i].key,  klist->keys[i].iv,
                  metadata, sizeof(METADATA_INFO), (uint8_t *) &metadata_info);

        if (memcmp (metadata_info.key_pad, zero, 16) == 0 &&
                memcmp (metadata_info.iv_pad, zero, 16) == 0) {
            memcpy(metadata, &metadata_info, sizeof(METADATA_INFO));
            break;
        }
    }

    if (i >= klist->n)
        return -1;

    aes128ctr(metadata_info.key, metadata_info.iv,
              metadata + sizeof(METADATA_INFO),
              metadata_size - sizeof(METADATA_INFO),
              metadata + sizeof(METADATA_INFO));

    return i;
}
Ejemplo n.º 3
0
int sce_encrypt_header(u8 *ptr, struct key *k)
{
	u32 meta_offset;
	u32 meta_len;
	u64 header_len;
	u8 iv[16];

	meta_offset = be32(ptr + 0x0c);
	header_len  = be64(ptr + 0x10);
	meta_len = header_len - meta_offset;

	memcpy(iv, ptr + meta_offset + 0x40, 0x10);
	aes128ctr(ptr + meta_offset + 0x20,
		  iv,
		  ptr + meta_offset + 0x60,
		  meta_len - 0x60,
		  ptr + meta_offset + 0x60);

	aes256cbc_enc(k->key, k->iv,
	              ptr + meta_offset + 0x20,
		      0x40,
		      ptr + meta_offset + 0x20);


	return 0;
}
Ejemplo n.º 4
0
static void
paged_file_crypt_internal_decrypt (PagedFile *f)
{
  if (f->size - f->pos > 0) {
    if (f->crypt == PAGED_FILE_CRYPT_AES_128_CBC) {
      u8 iv[0x10];

      memcpy (iv, f->iv, 0x10);
      if ((f->size - f->pos) >= 0x10)
        memcpy (f->iv, f->ptr + f->size - 0x10, 0x10);
      aes128cbc (f->key, iv, f->ptr + f->pos, f->size - f->pos,
          f->ptr + f->pos);
    } else if (f->crypt == PAGED_FILE_CRYPT_AES_256_CBC) {
      u8 iv[0x10];

      memcpy (iv, f->iv, 0x10);
      if ((f->size - f->pos) >= 0x10)
        memcpy (f->iv, f->ptr + f->size - 0x10, 0x10);
      aes256cbc (f->key, iv, f->ptr + f->pos, f->size - f->pos, f->ptr + f->pos);
    } else if (f->crypt == PAGED_FILE_CRYPT_AES_128_CTR) {
      aes128ctr (f->key, f->iv, f->ptr + f->pos, f->size - f->pos, f->ptr + f->pos);
    } else if (f->crypt == PAGED_FILE_CRYPT_CUSTOM) {
      f->crypt_cb (f, PAGED_FILE_CRYPT_DECRYPT, f->ptr + f->pos,
          f->size - f->pos, f->crypt_cb_data);
    }
  }
}
Ejemplo n.º 5
0
static void decrypt_retail_pkg(void)
{
	u8 key[0x10];
	u8 iv[0x10];

	if (be16(pkg + 0x06) != 1)
		fail("invalid pkg type: %x", be16(pkg + 0x06));

	if (key_get_simple("gpkg-key", key, 0x10) < 0)
		fail("failed to load the package key.");

	memcpy(iv, pkg + 0x70, 0x10);
	aes128ctr(key, iv, pkg + offset, size, pkg + offset);
}
Ejemplo n.º 6
0
static void
paged_file_crypt_internal_encrypt (PagedFile *f)
{
  if (f->size > 0) {
    if (f->crypt == PAGED_FILE_CRYPT_AES_128_CBC) {
      aes128cbc_enc (f->key, f->iv, f->ptr, f->size, f->ptr);
      if (f->size >= 0x10)
        memcpy (f->iv, f->ptr + f->size - 0x10, 0x10);
    } else if (f->crypt == PAGED_FILE_CRYPT_AES_256_CBC) {
      aes256cbc_enc (f->key, f->iv, f->ptr, f->size, f->ptr);
      if (f->size >= 0x10)
        memcpy (f->iv, f->ptr + f->size - 0x10, 0x10);
    } else if (f->crypt == PAGED_FILE_CRYPT_AES_128_CTR) {
      aes128ctr (f->key, f->iv, f->ptr, f->size, f->ptr);
    } else if (f->crypt == PAGED_FILE_CRYPT_CUSTOM) {
      f->crypt_cb (f, PAGED_FILE_CRYPT_ENCRYPT, f->ptr, f->size,
          f->crypt_cb_data);
    }
  }
}
Ejemplo n.º 7
0
int sce_decrypt_data(u8 *ptr)
{
	u64 meta_offset;
	u32 meta_len;
	u32 meta_n_hdr;
	u64 header_len;
	u32 i;

	u64 offset;
	u64 size;
	u32 keyid;
	u32 ivid;
	u8 *tmp;

	u8 iv[16];

	meta_offset = be32(ptr + 0x0c);
	header_len  = be64(ptr + 0x10);
	meta_len = header_len - meta_offset;
	meta_n_hdr = be32(ptr + meta_offset + 0x60 + 0xc);

	for (i = 0; i < meta_n_hdr; i++) {
		tmp = ptr + meta_offset + 0x80 + 0x30*i;
		offset = be64(tmp);
		size = be64(tmp + 8);
		keyid = be32(tmp + 0x24);
		ivid = be32(tmp + 0x28);

		if (keyid == 0xffffffff || ivid == 0xffffffff)
			continue;

		memcpy(iv, ptr + meta_offset + 0x80 + 0x30 * meta_n_hdr + ivid * 0x10, 0x10);
		aes128ctr(ptr + meta_offset + 0x80 + 0x30 * meta_n_hdr + keyid * 0x10,
		          iv,
 		          ptr + offset,
			  size,
			  ptr + offset);
	}

	return 0;
}
Ejemplo n.º 8
0
int main(int argc, char* argv[]) {
  int i;
  u8 ecount_buf[0x10], iv[0x10];
  size_t countp;
  int num;

  if(argc < 4) {
    printf("usage: %s input.elf output.self keytype keysuffix\n", argv[0]);
    return -1;
  }

  Elf64_Ehdr input_elf_header;
  FILE *input_elf_file = fopen(argv[1], "rb");

  fseek(input_elf_file, 0, SEEK_END);
  int nlen = ftell(input_elf_file);
  fseek(input_elf_file, 0, SEEK_SET);
  input_elf_data = (u8*)malloc(nlen);
  fread(input_elf_data, 1, nlen, input_elf_file);
  fclose(input_elf_file);

  memcpy(&input_elf_header, input_elf_data, sizeof(input_elf_header));


  FILE *output_self_file = fopen(argv[2], "wb");


  printf("ELF header size @ %x\n", get_u16(&(input_elf_header.e_ehsize)) );
  printf("%d program headers @ %64llX\n", get_u16(&(input_elf_header.e_phnum)), get_u64(&(input_elf_header.e_phoff)));
  printf("%d section headers @ %64llX\n", get_u16(&(input_elf_header.e_shnum)), get_u64(&(input_elf_header.e_shoff)));

  Self_Shdr output_self_header; memset(&output_self_header, 0, sizeof(output_self_header));
  Self_Ehdr output_extended_self_header; memset(&output_extended_self_header, 0, sizeof(output_extended_self_header));
  Self_Ihdr output_self_info_header; memset(&output_self_info_header, 0, sizeof(output_self_info_header));

  set_u32(&(output_self_header.s_magic), 0x53434500);
  set_u32(&(output_self_header.s_hdrversion), 2);
  set_u16(&(output_self_header.s_flags), 1);
  set_u16(&(output_self_header.s_hdrtype), 1);
  // header size and file size aren't known yet

  set_u64(&(output_extended_self_header.e_magic), 3);
  set_u64(&(output_extended_self_header.e_ihoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr));
  set_u64(&(output_extended_self_header.e_ehoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr)+sizeof(Self_Ihdr));
  set_u64(&(output_extended_self_header.e_phoff), sizeof(Self_Shdr)+sizeof(Self_Ehdr)+sizeof(Self_Ihdr)+get_u64(&(input_elf_header.e_phoff)));
  // section header offset unknown

  set_u64(&(output_self_info_header.i_authid), 0x1070000500000001LL);
  set_u32(&(output_self_info_header.i_magic), 0x01000002);
  set_u32(&(output_self_info_header.i_apptype), 4);
  set_u64(&(output_self_info_header.i_version), 0x0003000000000000LL);

// set static data
  int phnum = get_u16(&(input_elf_header.e_phnum));
  u32 phsize = (sizeof(Elf64_Phdr)*get_u16(&(input_elf_header.e_phnum))); 

  Self_SDKversion sdkversion;
  Self_Cflags cflags;
  memcpy(&sdkversion, sdkversion_static, sizeof(Self_SDKversion));
  memcpy(&cflags, cflags_static, sizeof(Self_Cflags));

  int running_size = (sizeof(output_self_header)+sizeof(output_extended_self_header)+sizeof(output_self_info_header)+sizeof(input_elf_header)+phsize+0xF)&0xFFFFFFF0;

  set_u64(&(output_extended_self_header.e_pmoff), running_size); running_size += phnum*sizeof(Self_PMhdr);
  set_u64(&(output_extended_self_header.e_svoff), running_size); running_size += sizeof(Self_SDKversion);
  set_u64(&(output_extended_self_header.e_cfoff), running_size); running_size += sizeof(Self_Cflags);
  set_u64(&(output_extended_self_header.e_cfsize), sizeof(Self_Cflags));
  set_u32(&(output_self_header.s_esize), running_size - sizeof(output_self_header));

  printf("running size is %X\n", running_size);

  int maxsection = 6;

  running_size += sizeof(metadata_crypt_header)+sizeof(segment_certification_header)+maxsection*(sizeof(segment_certification_segment)+sizeof(segment_certification_crypt_encrypted))+sizeof(segment_certification_sign)+sizeof(nubpadding_static);

  printf("running size is %X\n", running_size);

  set_u64(&(output_self_header.s_shsize), running_size);

// init randomness
  gmp_randstate_t r_state;
  gmp_randinit_default(r_state);
  gmp_randseed_ui(r_state, time(NULL));

// loop through the sections

  segment_certification_header segment_header; memset(&segment_header, 0, sizeof(segment_header));
  Self_Section first_section;
  Self_Section* section_ptr = &first_section;

  set_u64(&(segment_header.signature_offset), running_size-sizeof(segment_certification_sign));
  set_u32(&(segment_header.unknown1), 1);
  set_u32(&(segment_header.segment_count), phnum);
  set_u32(&(segment_header.crypt_len), (phnum*sizeof(segment_certification_crypt_encrypted))/0x10);

  Elf64_Phdr* elf_segment = (Elf64_Phdr*)(&input_elf_data[get_u64(&(input_elf_header.e_phoff))]);

  for(i=0;i<phnum;i++) {
    memset(section_ptr, 0, sizeof(Self_Section));

    //set_u64(&(section_ptr->enc_segment.segment_offset), get_u64(&(elf_segment->p_vaddr)));
    set_u64(&(section_ptr->enc_segment.segment_offset), running_size);
    set_u64(&(section_ptr->enc_segment.segment_size), get_u64(&(elf_segment->p_filesz)));
    set_u32(&(section_ptr->enc_segment.segment_crypt_flag), 2);

    set_u32(&(section_ptr->enc_segment.segment_sha1_index), i*8);
    set_u32(&(section_ptr->enc_segment.segment_erk_index), i*8+6);
    set_u32(&(section_ptr->enc_segment.segment_riv_index), i*8+7);

    set_u32(&(section_ptr->enc_segment.segment_number), i);
    set_u32(&(section_ptr->enc_segment.unknown2), 2);
    set_u32(&(section_ptr->enc_segment.unknown3), 3);
    set_u32(&(section_ptr->enc_segment.unknown4), 2);

    set_u64(&(section_ptr->pmhdr.pm_offset), running_size);
    set_u64(&(section_ptr->pmhdr.pm_size), get_u64(&(elf_segment->p_filesz)));
    set_u32(&(section_ptr->pmhdr.pm_compressed), 1);
    set_u32(&(section_ptr->pmhdr.pm_encrypted), 1);

    mpz_t riv, erk, hmac;
    mpz_init(riv); mpz_init(erk); mpz_init(hmac);
    mpz_urandomb(erk, r_state, 128);
    mpz_urandomb(riv, r_state, 128);
    mpz_urandomb(hmac, r_state, 512);

    mpz_export(section_ptr->crypt_segment.erk, &countp, 1, 0x10, 1, 0, erk);
    mpz_export(section_ptr->crypt_segment.riv, &countp, 1, 0x10, 1, 0, riv);
    mpz_export(section_ptr->crypt_segment.hmac, &countp, 1, 0x40, 1, 0, hmac);

    section_ptr->rlen = get_u64(&(elf_segment->p_filesz));
    section_ptr->len = ((section_ptr->rlen)+0xF)&0xFFFFFFF0;
    section_ptr->data = (u8*)malloc(section_ptr->len);

    u32 in_data_offset = get_u64(&(elf_segment->p_offset)); // + get_u16(&(input_elf_header.e_ehsize)) + (sizeof(Elf64_Phdr)*get_u16(&(input_elf_header.e_phnum)));
    u8* in_data = &input_elf_data[in_data_offset];

    printf("processing segment %d with len %x offset %x\n", i, section_ptr->len, in_data_offset);
    //hexdump((u8*)elf_segment, sizeof(Elf64_Phdr));


    /*SHA_CTX c;
    SHA1_ghetto_init(&c, section_ptr->crypt_segment.hmac);
    SHA1_Update(&c, in_data, section_ptr->rlen);
    SHA1_ghetto_final(section_ptr->crypt_segment.sha1, &c, section_ptr->crypt_segment.hmac);*/
    sha1_hmac(section_ptr->crypt_segment.hmac, in_data, section_ptr->rlen, section_ptr->crypt_segment.sha1);

    memset(ecount_buf, 0, 16); num=0;
    AES_set_encrypt_key(section_ptr->crypt_segment.erk, 128, &aes_key);
    memcpy(iv, section_ptr->crypt_segment.riv, 16);

    #ifdef NO_CRYPT
      memcpy(section_ptr->data, in_data, section_ptr->len);   
    #else
      //AES_ctr128_encrypt(in_data, section_ptr->data, section_ptr->len, &aes_key, iv, ecount_buf, &num);
      aes128ctr((u8*)&aes_key, iv, in_data, section_ptr->len, section_ptr->data);
    #endif

    running_size += section_ptr->len;

// next
    if(i != phnum-1) {
      section_ptr->next_section = malloc(sizeof(Self_Section));
    }
    elf_segment += 1;  // 1 is sizeof(Elf64_Phdr)
    section_ptr = section_ptr->next_section;
  }

  printf("segment processing done\n");


// section table offset
  set_u64(&(output_extended_self_header.e_shoff), running_size);

// lay out the metadata
  u8 metadata[0x2000]; memset(metadata, 0, 0x2000);
  u32 metadata_len = 0;

  memcpy(&metadata[metadata_len], &output_self_header, sizeof(output_self_header)); metadata_len += sizeof(output_self_header);
  memcpy(&metadata[metadata_len], &output_extended_self_header, sizeof(output_extended_self_header)); metadata_len += sizeof(output_extended_self_header);
  memcpy(&metadata[metadata_len], &output_self_info_header, sizeof(output_self_info_header)); metadata_len += sizeof(output_self_info_header);
  memcpy(&metadata[metadata_len], &input_elf_header, sizeof(input_elf_header)); metadata_len += sizeof(input_elf_header);
  memcpy(&metadata[metadata_len], &input_elf_data[get_u64(&(input_elf_header.e_phoff))], phsize); metadata_len += phsize;
  metadata_len = (metadata_len+0xF)&0xFFFFFFF0;

  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->pmhdr), sizeof(section_ptr->pmhdr)); metadata_len += sizeof(section_ptr->pmhdr);
    section_ptr = section_ptr->next_section;
  }

  memcpy(&metadata[metadata_len], &sdkversion, sizeof(sdkversion)); metadata_len += sizeof(sdkversion);
  memcpy(&metadata[metadata_len], &cflags, sizeof(cflags)); metadata_len += sizeof(cflags);

  printf("top half of metadata ready\n");

// generate metadata encryption keys
  mpz_t bigriv, bigerk;
  mpz_init(bigriv); mpz_init(bigerk);
  mpz_urandomb(bigerk, r_state, 128);
  mpz_urandomb(bigriv, r_state, 128);

  metadata_crypt_header md_header;

  mpz_export(md_header.erk, &countp, 1, 0x10, 1, 0, bigerk);
  mpz_export(md_header.riv, &countp, 1, 0x10, 1, 0, bigriv);

  memcpy(&metadata[metadata_len], &md_header, sizeof(md_header)); metadata_len += sizeof(md_header);
  memcpy(&metadata[metadata_len], &segment_header, sizeof(segment_header)); metadata_len += sizeof(segment_header);

// copy section data
  int csection;

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->enc_segment), sizeof(section_ptr->enc_segment)); metadata_len += sizeof(section_ptr->enc_segment);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != NULL) {
    memcpy(&metadata[metadata_len], &(section_ptr->crypt_segment), sizeof(section_ptr->crypt_segment)); metadata_len += sizeof(section_ptr->crypt_segment);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

// nubpadding time
  memcpy(&metadata[metadata_len], nubpadding_static, sizeof(nubpadding_static)); metadata_len += sizeof(nubpadding_static);

// sign shit
  u8 digest[0x14];
  sha1(metadata, metadata_len, digest);
  printf("metadata len is %X\n", metadata_len);
  //hexdump(metadata, metadata_len);
  //hexdump_nl(digest, 0x14);
  segment_certification_sign all_signed;
  memset(&all_signed, 0, sizeof(all_signed));

#ifdef GEOHOT_SIGN
  mpz_t n,k,da,kinv,r,cs,z;
  mpz_init(n); mpz_init(k); mpz_init(da); mpz_init(r); mpz_init(cs); mpz_init(z); mpz_init(kinv);
  mpz_import(r, 0x14, 1, 1, 0, 0, appold_R);
  mpz_import(n, 0x14, 1, 1, 0, 0, appold_n);
  mpz_import(k, 0x14, 1, 1, 0, 0, appold_K);
  mpz_import(da, 0x14, 1, 1, 0, 0, appold_Da);
  mpz_invert(kinv, k, n);

  mpz_import(z, 0x14, 1, 1, 0, 0, digest);

  mpz_mul(cs, r, da); mpz_mod(cs, cs, n);
  mpz_add(cs, cs, z); mpz_mod(cs, cs, n);
  mpz_mul(cs, cs, kinv); mpz_mod(cs, cs, n);

  mpz_export(all_signed.R, &countp, 1, 0x14, 1, 0, r);
  mpz_export(all_signed.S, &countp, 1, 0x14, 1, 0, cs);
#else
  get_keys(argv[3], argv[4]);
  //ecdsa_set_curve(appnew_ctype);
  //ecdsa_set_pub(appnew_pub);
  //ecdsa_set_priv(appnew_priv);
  //ecdsa_sign(digest, all_signed.R, all_signed.S);
#endif

  memcpy(&metadata[metadata_len], &all_signed, sizeof(all_signed)); metadata_len += sizeof(all_signed);

// encrypt metadata
  int metadata_offset = get_u32(&(output_self_header.s_esize)) + sizeof(Self_Shdr);

#ifndef NO_CRYPT
  /*memset(ecount_buf, 0, 16); num=0;
  AES_set_encrypt_key(&metadata[metadata_offset], 128, &aes_key);
  memcpy(iv, &metadata[metadata_offset+0x20], 16);
  //AES_ctr128_encrypt(&metadata[0x40+metadata_offset], &metadata[0x40+metadata_offset], metadata_len-metadata_offset-0x40, &aes_key, iv, ecount_buf, &num);
  aes128ctr(&metadata[0x20+metadata_offset], &metadata[0x40+metadata_offset], &metadata[0x60+metadata_offset], metadata_len-metadata_offset-0x60, &metadata[0x60+metadata_offset]);
  printf("encrypted metadata\n");

  //AES_set_encrypt_key(appold_erk, 256, &aes_key);
  //memcpy(iv, appold_riv, 16);
  AES_set_encrypt_key(appnew_erk, 256, &aes_key);
  memcpy(iv, appnew_riv, 16);
  //AES_cbc_encrypt(&metadata[metadata_offset], &metadata[metadata_offset], 0x40, &aes_key, iv, AES_ENCRYPT);
  aes256cbc_enc(appnew_erk, appnew_riv, &metadata[metadata_offset], 0x40, &metadata[metadata_offset]);

  printf("encrypted keys\n");*/
  //k.key = appnew_erk;
  //k.iv = appnew_riv;
  sce_encrypt_header(metadata, &ks);
#endif

// write the output self
  fwrite(metadata, 1, metadata_len, output_self_file);

  csection = 0;
  section_ptr = &first_section;
  while(section_ptr != 0) {
    printf("writing section with size %X\n", section_ptr->len);
    fwrite(section_ptr->data, 1, section_ptr->len, output_self_file);
    section_ptr = section_ptr->next_section;
    if((++csection) == maxsection) break;
  }

  fwrite(&input_elf_data[get_u64(&(input_elf_header.e_shoff))], sizeof(Elf64_Shdr), get_u16(&(input_elf_header.e_shnum)), output_self_file);

  fclose(output_self_file);
}
Ejemplo n.º 9
0
int
self_load_sections (FILE *in, SELF *self, ELF *elf, ELF_PHDR **phdr,
                    METADATA_HEADER *metadata_header, METADATA_SECTION_HEADER **section_headers,
                    uint8_t **keys, SELF_SECTION **sections)
{
    uint32_t num_sections;
    uint32_t i;
    uint64_t size;
    uint32_t elf_size;
    METADATA_SECTION_HEADER *hdr;
    uint8_t *temp_data;
    size = 0;
    num_sections = metadata_header->section_count + 1;

    *sections = malloc (sizeof(SELF_SECTION) * num_sections);
    // ELF header
    for (i = 0; i < num_sections; i++) {
        if (i == 0) {
            hdr = (*section_headers);
            elf_size = elf->header_size + (elf->phent_size * elf->phnum);
            size = hdr->data_offset - self->header_len;
            if (size < elf_size)
                size = elf_size;
            (*sections)[i].offset = 0;
            (*sections)[i].size = size;
            (*sections)[i].data = malloc (size);

            fseek (in, self->header_len, SEEK_SET);
            if (fread ((*sections)[0].data, 1, size, in) != size) {
                ERROR (-6, "Couldn't read section header");
            }

            fseek (in, self->elf_offset, SEEK_SET);
            if (fread ((*sections)[0].data, 1, size, in) != size) {
                ERROR (-6, "Couldn't read section elf");
            }
        } else {
            hdr = (*section_headers) + i - 1;
            if (hdr->type == 2) {
                // phdr
                size = (*phdr)[hdr->program_idx].segment_size;
                (*sections)[i].offset = (*phdr)[hdr->program_idx].offset_in_file;
            } else if (hdr->type == 1) {
                // shdr
                size = (*section_headers)[i-1].data_size;
                (*sections)[i].offset = elf->shdr_offset;
            } else {
                (*sections)[i].offset = UINT64_MAX;
                printf("Section %d unkown type: %d. Skipping!\n", i, hdr->type);
            }

            (*sections)[i].size = size;
            (*sections)[i].data = malloc (size);

            temp_data = malloc (hdr->data_size);
            fseek (in, hdr->data_offset, SEEK_SET);
            if (fread (temp_data, 1, hdr->data_size, in) != hdr->data_size) {
                ERROR (-6, "Couldn't read section");
            }

//      if (hdr->encrypted == 3 && self->flags != 0x8000)
            if (hdr->encrypted == 3)
                aes128ctr(*keys + 0x10 * hdr->key_idx, *keys + 0x10 * hdr->iv_idx,
                          temp_data, hdr->data_size, temp_data);

            if (hdr->compressed == 2)
                decompress(temp_data, hdr->data_size, (*sections)[i].data, size);
            else
                memcpy ((*sections)[i].data, temp_data, size);

            free (temp_data);
        }
    }

    return num_sections;
}
Ejemplo n.º 10
0
int sce_decrypt_header(u8 *ptr, struct keylist *klist)
{
	u32 meta_offset;
	u32 meta_len;
	u64 header_len;
	u32 i, j, k;
	u8 tmp[0x40];
	int success = 0;


	meta_offset = be32(ptr + 0x0c);
	header_len  = be64(ptr + 0x10);
    unsigned char *erkptr;
    unsigned char *rivptr;
	for (i = 0; i < klist->n; i++) {
		erkptr = (unsigned char *)&klist->keys[i].key;
		rivptr = (unsigned char *)&klist->keys[i].iv;
		printf(" ERK: ");
		for(k=0;k<32;k++){
	printf("\\x");
        printf("%2.2X", *erkptr++);
		}
        printf(" RIV: ");
        for(k=0;k<16;k++){
	printf("\\x");
        printf("%2.2X", *rivptr++);
        }
        printf(" ID: %u " ,i);
		aes256cbc(klist->keys[i].key,
			  klist->keys[i].iv,
			  ptr + meta_offset + 0x20,
			  0x40,
			  tmp);

		success = 1;
		for (j = 0x10; j < (0x10 + 0x10); j++)
			if (tmp[j] != 0)
				success = 0;

		for (j = 0x30; j < (0x30 + 0x10); j++)
			if (tmp[j] != 0)
			       success = 0;

		if (success == 1) {
			memcpy(ptr + meta_offset + 0x20, tmp, 0x40);
			printf("...Yep!\n");
			break;
		}
		if (success == 0)
            printf("..Nope\n");
        else
            printf("\n");
	}

	if (success != 1)
		return -1;

	memcpy(tmp, ptr + meta_offset + 0x40, 0x10);
	aes128ctr(ptr + meta_offset + 0x20,
		  tmp,
		  ptr + meta_offset + 0x60,
		  0x20,
		  ptr + meta_offset + 0x60);

	meta_len = header_len - meta_offset;

	aes128ctr(ptr + meta_offset + 0x20,
		  tmp,
		  ptr + meta_offset + 0x80,
		  meta_len - 0x80,
		  ptr + meta_offset + 0x80);

	return i;
}