Example #1
0
//TODO: The fwrite/fread error checking was broken.
//Maybe the MS runtime is returning the number of bytes written instead of the element count?
BOOL __stdcall np_sign_file(s8 *fname)
{
	u8 padding_data[0x10] = 
	{
		0xbc, 0x3f, 0x7a, 0x48, 0xaf, 0x45, 0xef, 0x28, 0x3a, 0x05, 0x98, 0x10, 0xbc, 0x3f, 0x7a, 0x48
	};

	keyset_t *ks;
	FILE *fp = NULL;
	u8 *buffer = NULL;
	u32 length;
	u32 padding;
	u8 hash[0x14], R[0x15], S[0x15];

	//Try to find keyset.
	if((ks = keyset_find_by_name(CONFIG_NP_SIG_KNAME)) == NULL)
		return FALSE;

	if((fp = fopen(fname, "r+b")) == NULL)
		return FALSE;

	fseek(fp, 0, SEEK_END);
	length = ftell(fp);

	padding = length % 0x10;
	if(padding > 0)
	{
		fwrite(padding_data, sizeof(u8), padding, fp);
		length += padding;
	}

	fseek(fp, 0, SEEK_SET);
	if((buffer = (u8 *)calloc(length, sizeof(char))) == NULL)
	{
		fclose(fp);
		return FALSE;
	}
	fread(buffer, sizeof(u8), length, fp);

	//Generate header hash.
	sha1(buffer, length, hash);

	//Generate signature.
	/* TODO: Set the right curve and private key */
	ecdsa_set_curve(ks->ctype | USE_VSH_CURVE);
	ecdsa_set_pub(ks->pub);
	ecdsa_set_priv(ks->priv);
	ecdsa_sign(hash, R, S);
	fseek(fp, 0, SEEK_END);
	fwrite(R + 1, 0x14, 1, fp);
	fwrite(S + 1, 0x14, 1, fp);
	/* Let's be as stupid as sony here... */
	fwrite(hash + 0xC, 8, 1, fp);

	free(buffer);
	fclose(fp);

	return TRUE;
}
Example #2
0
int add_npdrm_footer_sig(const char *filename) {
  FILE *fp; 

  uint8_t s[21]; 
  uint8_t r[21]; 
  uint8_t hash[20]; 

  static char padding[] = {
	0x8b, 0x3f, 0x7a,0x48,
	0xaf, 0x45, 0xef, 0x28,
	0x3a, 0x05, 0x98, 0x10,
	0xbc, 0x3f, 0x7a, 0x48
  };
  
  keyset_t *keyset = find_keyset_by_name("NP_sig");
  
  if ( !keyset)
	return 0;
	
  fp = fopen(filename, "r+b");
  if (!fp)
    return 0;
	
  fseek(fp, 0, SEEK_END);
  size_t size = ftell (fp);
  // Error ? SCETool takes left_not_aligned as (size & 0xF)
  size_t left_not_aligned = (0x10 - (size & 0xF)) & 0x0F;
  if (left_not_aligned) {
    fwrite(padding, 1, left_not_aligned, fp);
    size += left_not_aligned;
  }
  fseek(fp, 0, SEEK_SET);
  uint8_t *buffer = malloc(size);
  if (!buffer)  {
    fclose(fp);
    return 0;
  }

  if(fread(buffer, 1, size, fp) != size)
    return 0;
    
  
  sha1(buffer, size, hash);
  
  ecdsa_set_curve(keyset->ctype | 0x40);
  ecdsa_set_pub(keyset->pub_key);
  ecdsa_set_priv(keyset->priv_key);
  ecdsa_sign(r, s, hash);
  
  fseek(fp, 0, SEEK_END); 
  fwrite(&r[1], 20, 1, fp);
  fwrite(&s[1], 20, 1, fp);
  fwrite(&hash[12], 8, 1, fp);
  
  free(buffer);
  fclose(fp);  
  return 1;
}
Example #3
0
int edata_sign_free(u8 *edata_buf, u8 *pgd_key)
{
	MAC_KEY mkey;
	AES_ctx aes;
	u8 sha1_hash[20], license_key[16];
	int flag, i;

	printf("re-sign EDATA ...\n");

	flag = *(u8*)(edata_buf+15);

	// get license_key
	if(flag&1){
		sceDrmBBMacInit(&mkey, 3);
		sceDrmBBMacUpdate(&mkey, edata_buf, 0x80);
		bbmac_getkey(&mkey, edata_buf+0x80, license_key);
		if(verbose) hex_dump("license key", license_key, 16);
	}

	// change to use free license
	*(u32*)(edata_buf+8) = 0x01000000;

	// build ecdsa
	ecdsa_set_curve(&ecdsa_app);
	ecdsa_set_priv(priv_key_edata);
	SHA1(edata_buf, 0x58, sha1_hash);
	ecdsa_sign(sha1_hash, edata_buf+0x58, edata_buf+0x6c, NULL);

	// build BBMAC
	if(flag&1){
		sceDrmBBMacInit(&mkey, 3);
		sceDrmBBMacUpdate(&mkey, edata_buf, 0x80);
		sceDrmBBMacFinal(&mkey, edata_buf+0x80, license_key);
		bbmac_build_final2(3, edata_buf+0x80);
	}

	// build PGD key
	sceNpDrmGetFixedKey(pgd_key, (char*)(edata_buf+16), 0x01000000);
	if(verbose) hex_dump("get_fixed_key", pgd_key, 16);

	if(flag&1){
		for(i=0; i<16; i++){
			pgd_key[i] ^= license_key[i];
		}
	}

	AES_set_key(&aes, edat_aeskey, 128);
	AES_decrypt(&aes, pgd_key, pgd_key);
	if(verbose) hex_dump("new PGD key", pgd_key, 16);

	return 0;
}
Example #4
0
static void get_keys(const char *suffix)
{
	if (key_get(type, suffix, &ks) < 0)
		fail("key_get failed");

	if (ks.pub_avail < 0)
		fail("no public key available");

	if (ks.priv_avail < 0)
		fail("no private key available");

	if (ecdsa_set_curve(ks.ctype) < 0)
		fail("ecdsa_set_curve failed");

	ecdsa_set_pub(ks.pub);
	ecdsa_set_priv(ks.priv);
}