Esempio n. 1
0
/*
 * Hash the buffer and place the result in *shaStateP.
 */
void
sha_hash(shaState * shaStateP, const char *buffer, int bufferLen)
{
    sha_clear(shaStateP);
    sha_update(shaStateP, buffer, bufferLen);
    sha_finish(shaStateP);
}
Esempio n. 2
0
/*
static bool checkFileHash(wchar_t *path, uint8_t *checkhash) {
	FIL fil;
	uint8_t *buf;
	uint8_t hash[32];
	size_t size;
	mbedtls_sha256_context ctx;
	
	if (!FileOpen(&fil, path, false) || ((FileGetSize(&fil)) == 0 && (FileClose(&fil) || true))) return false;
	buf = __builtin_alloca(BUF_SIZE);
	mbedtls_sha256_init(&ctx);
	mbedtls_sha256_starts(&ctx, 0);
	while ((size = FileRead2(&fil, buf, BUF_SIZE))) mbedtls_sha256_update(&ctx, buf, size);
	FileClose(&fil);
	mbedtls_sha256_finish(&ctx, hash);
	return !memcmp(hash, checkhash, sizeof(hash));
}
*/
uint_fast8_t tmdValidateChunk(tmd_data *data, wchar_t *path, uint_fast16_t content_index, uint_fast8_t drive) { //validates loaded tmd content chunk records
	FIL fil;
	size_t size;
	wchar_t apppath[_MAX_LFN + 1];
	uint8_t hash[SHA_256_SIZE];
	uint8_t *buf = __builtin_alloca(BUF_SIZE);
	uint_fast16_t content_count;

	content_count = __builtin_bswap16(data->header.content_count);
	if (!data->content_chunk &&
		(data->content_chunk = __builtin_alloca(content_count * sizeof(tmd_content_chunk))) &&
		!tmdPreloadChunk(data, path, content_index)
	) return 0;

	for (uint_fast16_t info_index = 0, chunk_index = 0; chunk_index < content_count; info_index++) {
		for (uint_fast16_t chunk_count = __builtin_bswap16(data->content_info[info_index].content_command_count); chunk_count > 0; chunk_index++, chunk_count--) {
			if (content_index == CONTENT_INDEX_ALL || content_index == data->content_chunk[chunk_index].content_index) {
				sha_start(SHA_256_MODE, NULL);
				swprintf(apppath, _MAX_LFN + 1, L"%.*ls/%08lx%s", wcsrchr(path, L'/') - path, path, __builtin_bswap32(data->content_chunk[chunk_index].content_id), APP_EXT);
				size = __builtin_bswap32(data->content_chunk[chunk_index].content_size_lo);
				if (FileOpen(&fil, apppath, 0) && (FileGetSize(&fil) == size || (FileClose(&fil) && 0))) {
					while ((size = FileRead2(&fil, buf, BUF_SIZE))) sha_update(buf, size);
				} else if (!(apppath[wcslen(apppath) - strlen(APP_EXT)] = 0) && 
					FileOpen(&fil, apppath, 0) && (FileGetSize(&fil) == size || (FileClose(&fil) && 0))
				) {
					aes_key Key = {&(aes_key_data){{0}}, AES_CNT_INPUT_BE_NORMAL, 0x2C, NORMALKEY};
					getTitleKey2(&Key, data->header.title_id, drive);
					aes_ctr ctr = {{{0}}, AES_CNT_INPUT_BE_NORMAL};
					aes_set_key(&Key);
					while ((size = FileRead2(&fil, buf, BUF_SIZE))) {
						aes(buf, buf, size, &ctr, AES_CBC_DECRYPT_MODE | AES_CNT_INPUT_BE_NORMAL | AES_CNT_OUTPUT_BE_NORMAL);
						sha_update(buf, size);
					}                    
				} else
					return 0;
				FileClose(&fil);
				sha_finish(hash);
				if (memcmp(hash, data->content_chunk[chunk_index].content_hash, sizeof(hash)))
					return 0;
			}
		}
	}
	return 1;
}