Пример #1
0
void Crypto::AesCtr(const u8* in, u32 size, const u8 key[kAes128KeySize], u8 ctr[kAesBlockSize], u8* out)
{
	aes_context ctx;
	u8 block[kAesBlockSize] = { 0 };
	size_t counterOffset = 0;

	aes_setkey_enc(&ctx, key, 128);
	aes_crypt_ctr(&ctx, size, &counterOffset, ctr, block, in, out);
}
Пример #2
0
void AesCtrCrypt(u8 *key, u8 *ctr, u8 *input, u8 *output, u64 length, u64 offset)
{
	u8 stream[16];
	aes_context aes;
	size_t nc_off = 0;
	
	clrmem(&aes,sizeof(aes_context));
	aes_setkey_enc(&aes, key, 128);
	SetAesCtrOffset(ctr,offset);
	
	aes_crypt_ctr(&aes, length, &nc_off, ctr, stream, input, output);
	
	
	return;
}
Пример #3
0
static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
        unsigned char *nonce_counter, unsigned char *stream_block,
        const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CTR)
    return aes_crypt_ctr( (aes_context *) ctx, length, nc_off, nonce_counter,
                          stream_block, input, output );
#else
    ((void) ctx);
    ((void) length);
    ((void) nc_off);
    ((void) nonce_counter);
    ((void) stream_block);
    ((void) input);
    ((void) output);

    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
#endif /* POLARSSL_CIPHER_MODE_CTR */
}
Пример #4
0
bool SELFDecrypter::LoadMetadata()
{
	aes_context aes;
	u32 metadata_info_size = sizeof(meta_info);
	u8 *metadata_info = (u8 *)malloc(metadata_info_size);
	u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info));
	u8 *metadata_headers = (u8 *)malloc(metadata_headers_size);

	// Locate and read the encrypted metadata info.
	self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr));
	self_f.Read(metadata_info, metadata_info_size);

	// Locate and read the encrypted metadata header and section header.
	self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr) + metadata_info_size);
	self_f.Read(metadata_headers, metadata_headers_size);

	// Find the right keyset from the key vault.
	SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version);

	// Copy the necessary parameters.
	u8 metadata_key[0x20];
	u8 metadata_iv[0x10];
	memcpy(metadata_key, keyset.erk, 0x20);
	memcpy(metadata_iv, keyset.riv, 0x10);

	// Check DEBUG flag.
	if ((sce_hdr.se_flags & 0x8000) != 0x8000)
	{
		// Decrypt the NPDRM layer.
		if (!DecryptNPDRM(metadata_info, metadata_info_size))
			return false;

		// Decrypt the metadata info.
		aes_setkey_dec(&aes, metadata_key, 256);  // AES-256
		aes_crypt_cbc(&aes, AES_DECRYPT, metadata_info_size, metadata_iv, metadata_info, metadata_info);
	}

	// Load the metadata info.
	meta_info.Load(metadata_info);

	// If the padding is not NULL for the key or iv fields, the metadata info
	// is not properly decrypted.
	if ((meta_info.key_pad[0] != 0x00) ||
		(meta_info.iv_pad[0] != 0x00))
	{
		LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!");
		return false;
	}

	// Perform AES-CTR encryption on the metadata headers.
	size_t ctr_nc_off = 0;
	u8 ctr_stream_block[0x10];
	aes_setkey_enc(&aes, meta_info.key, 128);
	aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers, metadata_headers);

	// Load the metadata header.
	meta_hdr.Load(metadata_headers);

	// Load the metadata section headers.
	meta_shdr.clear();
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		meta_shdr.emplace_back();
		meta_shdr.back().Load(metadata_headers + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i);
	}

	// Copy the decrypted data keys.
	data_keys_length = meta_hdr.key_count * 0x10;
	data_keys = (u8 *) malloc (data_keys_length);
	memcpy(data_keys, metadata_headers + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length);

	return true;
}
Пример #5
0
bool SELFDecrypter::DecryptData()
{
	aes_context aes;

	// Calculate the total data size.
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		if (meta_shdr[i].encrypted == 3)
		{
			if ((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count))
				data_buf_length += meta_shdr[i].data_size;
		}
	}

	// Allocate a buffer to store decrypted data.
	data_buf = (u8*)malloc(data_buf_length);

	// Set initial offset.
	u32 data_buf_offset = 0;

	// Parse the metadata section headers to find the offsets of encrypted data.
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		size_t ctr_nc_off = 0;
		u8 ctr_stream_block[0x10];
		u8 data_key[0x10];
		u8 data_iv[0x10];

		// Check if this is an encrypted section.
		if (meta_shdr[i].encrypted == 3)
		{
			// Make sure the key and iv are not out of boundaries.
			if((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count))
			{
				// Get the key and iv from the previously stored key buffer.
				memcpy(data_key, data_keys + meta_shdr[i].key_idx * 0x10, 0x10);
				memcpy(data_iv, data_keys + meta_shdr[i].iv_idx * 0x10, 0x10);

				// Allocate a buffer to hold the data.
				u8 *buf = (u8 *)malloc(meta_shdr[i].data_size);

				// Seek to the section data offset and read the encrypted data.
				self_f.Seek(meta_shdr[i].data_offset);
				self_f.Read(buf, meta_shdr[i].data_size);

				// Zero out our ctr nonce.
				memset(ctr_stream_block, 0, sizeof(ctr_stream_block));

				// Perform AES-CTR encryption on the data blocks.
				aes_setkey_enc(&aes, data_key, 128);
				aes_crypt_ctr(&aes, meta_shdr[i].data_size, &ctr_nc_off, data_iv, ctr_stream_block, buf, buf);

				// Copy the decrypted data.
				memcpy(data_buf + data_buf_offset, buf, meta_shdr[i].data_size);

				// Advance the buffer's offset.
				data_buf_offset += meta_shdr[i].data_size;

				// Release the temporary buffer.
				free(buf);
			}
		}
	}

	return true;
}
Пример #6
0
bool SCEDecrypter::LoadMetadata(const u8 erk[32], const u8 riv[16])
{
	aes_context aes;
	const auto metadata_info = std::make_unique<u8[]>(sizeof(meta_info));
	const auto metadata_headers_size = sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info));
	const auto metadata_headers = std::make_unique<u8[]>(metadata_headers_size);

	// Locate and read the encrypted metadata info.
	sce_f.seek(sce_hdr.se_meta + sizeof(sce_hdr));
	sce_f.read(metadata_info.get(), sizeof(meta_info));

	// Locate and read the encrypted metadata header and section header.
	sce_f.seek(sce_hdr.se_meta + sizeof(sce_hdr) + sizeof(meta_info));
	sce_f.read(metadata_headers.get(), metadata_headers_size);

	// Copy the necessary parameters.
	u8 metadata_key[0x20];
	u8 metadata_iv[0x10];
	memcpy(metadata_key, erk, 0x20);
	memcpy(metadata_iv, riv, 0x10);

	// Check DEBUG flag.
	if ((sce_hdr.se_flags & 0x8000) != 0x8000)
	{
		// Decrypt the metadata info.
		aes_setkey_dec(&aes, metadata_key, 256);  // AES-256
		aes_crypt_cbc(&aes, AES_DECRYPT, sizeof(meta_info), metadata_iv, metadata_info.get(), metadata_info.get());
	}

	// Load the metadata info.
	meta_info.Load(metadata_info.get());

	// If the padding is not NULL for the key or iv fields, the metadata info
	// is not properly decrypted.
	if ((meta_info.key_pad[0] != 0x00) ||
		(meta_info.iv_pad[0] != 0x00))
	{
		LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!");
		return false;
	}

	// Perform AES-CTR encryption on the metadata headers.
	size_t ctr_nc_off = 0;
	u8 ctr_stream_block[0x10];
	aes_setkey_enc(&aes, meta_info.key, 128);
	aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers.get(), metadata_headers.get());

	// Load the metadata header.
	meta_hdr.Load(metadata_headers.get());

	// Load the metadata section headers.
	meta_shdr.clear();
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		meta_shdr.emplace_back();
		meta_shdr.back().Load(metadata_headers.get() + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i);
	}

	// Copy the decrypted data keys.
	data_keys_length = meta_hdr.key_count * 0x10;
	data_keys = std::make_unique<u8[]>(data_keys_length);
	memcpy(data_keys.get(), metadata_headers.get() + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length);

	return true;
}