Title Updates
Jump to navigation
Jump to search
Title update downloads are no longer as easy on on PS3. For PSVita title updates, the following path structure is used:
https://gs-sec.ww.|NETWORK|.dl.playstation.net/pl/np/|TITLEID|/|HASH|/|TITLEID|-ver.xml
- NETWORK can be np, sp-int, prod-qa, rc, or e1-np.
- TITLEID is the TitleId of the app. For example: PCSA00007.
- HASH is a secret calculated hash based on the below algorithm:
int main(void) { char network[0x10]; char titleid[0x10]; // Secret HMAC key found in shell.self unsigned char key[0x20] = {0x9A, 0x9D, 0x07, 0xD5, 0x61, 0x9C, 0x3F, 0xFD, 0xDF, 0xF7, 0x58, 0xE3, 0xFC, 0x86, 0xC4, 0xB7, 0x79, 0xFD, 0x63, 0x2D, 0x8D, 0xD4, 0x22, 0x54, 0x35, 0xC2, 0xE6, 0x2B, 0x2F, 0x4A, 0x2E, 0x6B }; char uniqdata[0x20]; int i, res; unsigned char result[0x20]; memset(network, 0, 0x10); memset(uniqdata, 0, 0x20); memset(result, 0, 0x20); memset(titleid, 0, 0x10); printf("Enter network name (np, prod-qa, sp-int, rc, e1-np):"); scanf_s("%s", network, 0x10); printf("Enter titleid:"); scanf_s("%s", titleid, 0x10); sprintf_s(uniqdata, 0x20, "%s_%s", network, titleid); // Lovely obfuscation for(i=0; i<0x20; i++) key[i] ^= 0x7F; hmac_sha256(key, 0x20, uniqdata, strlen(uniqdata), result); printf("https://gs-sec.ww.%s.dl.playstation.net/pl/%s/%s/", network, network, titleid); for(i=0; i<0x20; i++) { printf("%02x", result[i]); } printf("/%s-ver.xml\n", titleid); // printf("%s\n", orig); return 0; }
The hmac_sha256 function is not normal either. The made a couple of error or tweaks so it was not standard. Below is their hmac_sha256 function.
/** * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) * @key: Key for HMAC operations * @key_len: Length of the key in bytes * @num_elem: Number of elements in the data vector * @addr: Pointers to the data areas * @len: Lengths of the data blocks * @mac: Buffer for the hash (32 bytes) */ void hmac_sha256_vector( u8 *key, size_t key_len, size_t num_elem, u8 *addr[], size_t *len, u8 *mac) { unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */ unsigned char tk[32]; u8 *_addr[6]; size_t _len[6], i; if (num_elem > 5) { /* * Fixed limit on the number of fragments to avoid having to * allocate memory (which could fail). */ return; } /* if key is longer than 64 bytes reset it to key = SHA256(key) */ if (key_len > 64) { sha256_vector(1, &key, &key_len, tk); key = tk; key_len = 32; } /* the HMAC_SHA256 transform looks like: * * SHA256(K XOR opad, SHA256(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* start out by storing key in ipad */ memset(k_pad, 0, sizeof(k_pad)); memcpy(k_pad, key, key_len); /* XOR key with ipad values */ for (i = 0; i < 64; i++) k_pad[i] ^= 0x36; /* perform inner SHA256 */ _addr[0] = k_pad; _len[0] = 64; for (i = 0; i < num_elem; i++) { _addr[i + 1] = addr[i]; _len[i + 1] = len[i]; } sha256_vector(1 + num_elem, _addr, _len, mac); // NOTE: SCE HACK - they removed the clearing of the pad in their version. //memset(k_pad, 0, sizeof(k_pad)); //memcpy(k_pad, key, key_len); /* XOR key with opad values */ for (i = 0; i < 64; i++) // NOTE: SCE HACK - they changed the normal 0x5C value to 0x6A k_pad[i] ^= 0x6A; /* perform outer SHA256 */ _addr[0] = k_pad; _len[0] = 64; _addr[1] = mac; _len[1] = SHA256_MAC_LEN; sha256_vector(2, _addr, _len, mac); }