示例#1
0
文件: aes.cpp 项目: Yogesh2811/dipl
void encode_block(BYTE* counter, BYTE* dst, BYTE round_key[ROUND_KEY_SIZE][BLOCK_SIZE]){
    unsigned char temp[BLOCK_SIZE];

    xor_key(counter, temp, round_key[0]);
    for(int i = 1; i < ROUNDS; i++){
        sub_bytes(temp, dst);
        shift_rows(dst, temp);
        mix_columns(temp, dst);
        xor_key(dst, temp, round_key[i]);
    }
    sub_bytes(temp,dst);
    shift_rows(dst,temp);
    xor_key(temp,dst,round_key[ROUNDS]);
}
示例#2
0
文件: aes.cpp 项目: Yogesh2811/dipl
void decode_block(BYTE* counter, BYTE* dst, BYTE round_key[ROUND_KEY_SIZE][BLOCK_SIZE]){
    unsigned char temp[BLOCK_SIZE];

    xor_key(counter,temp,round_key[ROUNDS]);
    //memcpy(dst, round_key[ROUNDS], 16);
    shift_rows_inv(temp,dst);
    sub_bytes_inv(dst,temp);

    for(int i = ROUNDS-1; i > 0; i--){ 
        xor_key(temp, dst, round_key[i]);
        mix_columns_inv(dst, temp);
        shift_rows_inv(temp, dst);
        sub_bytes_inv(dst, temp);
    } 
    xor_key(temp, dst, round_key[0]);
}
示例#3
0
void sha1_ctr_encrypt(u8 *data, int size, int offset, u8 *sha1_key)
{
	u8 ikey[0x40], xkey[0x14];
	int i;

	memcpy(ikey, sha1_key, 0x40);

	for(i=0; i<offset; i+=16){
		key_inc(ikey+0x38, 7);
	}

	for(i=0; i<size; i+=16){
		SHA1(ikey, 0x40, xkey);
		xor_key(data+i, xkey, 16);
		key_inc(ikey+0x38, 7);
	}
}
示例#4
0
/* aes_ctr_encrypt */
void aes_ctr_encrypt(u8 *data, int size, int offset, u8 *file_key, u8 *aes_key)
{
	AES_ctx cpkg;
	u8 ikey[16], xkey[16];
	int i;

	AES_set_key(&cpkg, aes_key, 128);
	memcpy(ikey, file_key, 16);

	for(i=0; i<offset; i+=16){
		key_inc(ikey, 15);
	}

	for(i=0; i<size; i+=16){
		memcpy(xkey, ikey, 16);
		AES_encrypt(&cpkg, xkey, xkey);
		xor_key(data+i, xkey, 16);
		key_inc(ikey, 15);
	}
}
示例#5
0
int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd)
{
	unsigned char dev[0x60] = { 0 };
	unsigned char key[0x10] = { 0 };

	// Build the dev buffer (first 0x60 bytes of NPD header in big-endian).
	memcpy(dev, npd, 0x60);

	// Fix endianness.
	int version = swap32(npd->version);
	int license = swap32(npd->license);
	int type = swap32(npd->type);
	memcpy(dev + 0x4, &version, 4);
	memcpy(dev + 0x8, &license, 4);
	memcpy(dev + 0xC, &type, 4);

	// Check for an empty dev_hash (can't validate if devklic is NULL);
	bool isDevklicEmpty = true;
	for (int i = 0; i < 0x10; i++)
	{
		if (klicensee[i] != 0)
		{
			isDevklicEmpty = false;
			break;
		}
	}

	if (isDevklicEmpty)
	{
		// Allow empty dev hash.
		return 1;
	}
	else
	{
		// Generate klicensee xor key.
		xor_key(key, klicensee, NP_OMAC_KEY_2);

		// Hash with generated key and compare with dev_hash.
		return cmac_hash_compare(key, 0x10, dev, 0x60, npd->dev_hash, 0x10);
	}
}
示例#6
0
文件: aes.cpp 项目: Yogesh2811/dipl
void AES::srtp_decode(BYTE* src, BYTE* dst, BYTE* key, BYTE* iv, int length){
    LOG_MSG("AES::srtp_decode(%s, %s, %s, %s, %d)",src,dst,key,iv,length);
    BYTE counter[BLOCK_SIZE] = {0};
    memcpy(counter, iv, BLOCK_SIZE);

    unsigned char round_key[ROUND_KEY_SIZE][BLOCK_SIZE];
    expand_key(key,round_key);
    
    int i = 0, j = 0;

    for( ; i < length; i+=BLOCK_SIZE){
        decode_block(counter, dst+i, round_key);
        xor_key(dst+i,dst+i,src+i);
        update_counter(counter);
    }

    BYTE last_block[BLOCK_SIZE];
    decode_block(counter, last_block, round_key);
    for(i=i-BLOCK_SIZE; i < length; i++, j++){
        dst[i] = last_block[j] ^ src[i];
    }
}
示例#7
0
bool EDATADecrypter::ReadHeader()
{
	edata_file.seek(0);
	// Read in the NPD and EDAT/SDAT headers.
	read_npd_edat_header(&edata_file, npdHeader, edatHeader);

	unsigned char npd_magic[4] = { 0x4E, 0x50, 0x44, 0x00 };  //NPD0
	if (memcmp(&npdHeader.magic, npd_magic, 4))
	{
		return false;
	}

	// Check for SDAT flag.
	if ((edatHeader.flags & SDAT_FLAG) == SDAT_FLAG)
	{
		// Generate SDAT key.
		xor_key(dec_key.data(), npdHeader.dev_hash, SDAT_KEY);
	}
	else
	{
		// verify key
		if (validate_dev_klic(dev_key.data(), &npdHeader) == 0)
		{
			LOG_ERROR(LOADER, "EDAT: Failed validating klic");
			return false;
		}

		// Select EDAT key.
		if ((npdHeader.license & 0x3) == 0x3)           // Type 3: Use supplied devklic.
			dec_key = std::move(dev_key);
		else if ((npdHeader.license & 0x2) == 0x2)      // Type 2: Use key from RAP file (RIF key).
		{
			dec_key = std::move(rif_key);
			
			if (dec_key == std::array<u8, 0x10>{0})
			{
				LOG_WARNING(LOADER, "EDAT: Empty Dec key!");
			}
		}
		else if ((npdHeader.license & 0x1) == 0x1)      // Type 1: Use network activation.
		{
			LOG_ERROR(LOADER, "EDAT: Network license not supported!");
			return false;
		}
	}

	edata_file.seek(0);

	// k the ecdsa_verify function in this check_data function takes a ridiculous amount of time
	// like it slows down load time by a factor of x20, at least, so its ignored for now

	/*if (check_data(dec_key.data(), &edatHeader, &npdHeader, &sdata_file, false))
	{
		return false;
	}*/

	file_size = edatHeader.file_size;
	total_blocks = (u32)((edatHeader.file_size + edatHeader.block_size - 1) / edatHeader.block_size);

	return true;
}
示例#8
0
bool extract_all_data(const fs::file* input, const fs::file* output, const char* input_file_name, unsigned char* devklic, unsigned char* rifkey, bool verbose)
{
	// Setup NPD and EDAT/SDAT structs.
	NPD_HEADER NPD;
	EDAT_HEADER EDAT;

	// Read in the NPD and EDAT/SDAT headers.
	read_npd_edat_header(input, NPD, EDAT);

	unsigned char npd_magic[4] = {0x4E, 0x50, 0x44, 0x00};  //NPD0
	if (memcmp(&NPD.magic, npd_magic, 4))
	{
		LOG_ERROR(LOADER, "EDAT: %s has invalid NPD header or already decrypted.", input_file_name);
		return 1;
	}

	if (verbose)
	{
		LOG_NOTICE(LOADER, "NPD HEADER");
		LOG_NOTICE(LOADER, "NPD version: %d", NPD.version);
		LOG_NOTICE(LOADER, "NPD license: %d", NPD.license);
		LOG_NOTICE(LOADER, "NPD type: %d", NPD.type);
	}

	// Set decryption key.
	u8 key[0x10] = { 0 };

	// Check EDAT/SDAT flag.
	if ((EDAT.flags & SDAT_FLAG) == SDAT_FLAG)
	{
		if (verbose)
		{
			LOG_NOTICE(LOADER, "SDAT HEADER");
			LOG_NOTICE(LOADER, "SDAT flags: 0x%08X", EDAT.flags);
			LOG_NOTICE(LOADER, "SDAT block size: 0x%08X", EDAT.block_size);
			LOG_NOTICE(LOADER, "SDAT file size: 0x%08X", (u64)EDAT.file_size);
		}

		// Generate SDAT key.
		xor_key(key, NPD.dev_hash, SDAT_KEY);
	}
	else
	{
		if (verbose)
		{
			LOG_NOTICE(LOADER, "EDAT HEADER");
			LOG_NOTICE(LOADER, "EDAT flags: 0x%08X", EDAT.flags);
			LOG_NOTICE(LOADER, "EDAT block size: 0x%08X", EDAT.block_size);
			LOG_NOTICE(LOADER, "EDAT file size: 0x%08X", (u64)EDAT.file_size);
		}

		// Perform header validation (EDAT only).
		char real_file_name[MAX_PATH];
		extract_file_name(input_file_name, real_file_name);
		if (!validate_npd_hashes(real_file_name, devklic, &NPD, verbose))
		{
			// Ignore header validation in DEBUG data.
			if ((EDAT.flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG)
			{
				LOG_ERROR(LOADER, "EDAT: NPD hash validation failed!");
				return 1;
			}
		}

		// Select EDAT key.
		if ((NPD.license & 0x3) == 0x3)           // Type 3: Use supplied devklic.
			memcpy(key, devklic, 0x10);
		else if ((NPD.license & 0x2) == 0x2)      // Type 2: Use key from RAP file (RIF key).
		{
			memcpy(key, rifkey, 0x10);

			// Make sure we don't have an empty RIF key.
			int i, test = 0;
			for (i = 0; i < 0x10; i++)
			{
				if (key[i] != 0)
				{
					test = 1;
					break;
				}
			}

			if (!test)
			{
				LOG_ERROR(LOADER, "EDAT: A valid RAP file is needed for this EDAT file!");
				return 1;
			}
		}
		else if ((NPD.license & 0x1) == 0x1)      // Type 1: Use network activation.
		{
			LOG_ERROR(LOADER, "EDAT: Network license not supported!");
			return 1;
		}

		if (verbose)
		{
			int i;
			LOG_NOTICE(LOADER, "DEVKLIC: ");
			for (i = 0; i < 0x10; i++)
				LOG_NOTICE(LOADER, "%02X", devklic[i]);

			LOG_NOTICE(LOADER, "RIF KEY: ");
			for (i = 0; i < 0x10; i++)
				LOG_NOTICE(LOADER, "%02X", rifkey[i]);
		}
	}

	if (verbose)
	{
		int i;
		LOG_NOTICE(LOADER, "DECRYPTION KEY: ");
		for (i = 0; i < 0x10; i++)
			LOG_NOTICE(LOADER, "%02X", key[i]);
	}

	input->seek(0);
	if (check_data(key, &EDAT, &NPD, input, verbose))
	{
		LOG_ERROR(LOADER, "EDAT: Data parsing failed!");
		return 1;
	}

	input->seek(0);
	if (decrypt_data(input, output, &EDAT, &NPD, key, verbose))
	{
		LOG_ERROR(LOADER, "EDAT: Data decryption failed!");
		return 1;
	}

	return 0;
}