/*
 * partition_base - physical address of the partition
 * offset - offset, in blocks, of the data from the start of the partition
 * length - length, in bytes, of the data to be encrypted (multiple of 4)
 * black_data - virtual address that the encrypted data should be stored at
 * Note that this virtual address must be translatable using the __virt_to_phys
 * macro; ie, it can't be a specially mapped address.  To do encryption with those
 * addresses, use the scc_encrypt_region function directly.  This is to make
 * this function compatible with the user mode declaration, which does not know
 * the physical addresses of the data it is using.
 */
fsl_shw_return_t
do_scc_encrypt_region(fsl_shw_uco_t * user_ctx,
		      void *partition_base, uint32_t offset_bytes,
		      uint32_t byte_count, uint8_t * black_data,
		      uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode)
{
	scc_return_t scc_ret;
	fsl_shw_return_t retval = FSL_RETURN_ERROR_S;

#ifdef FSL_HAVE_SCC2

#ifdef DIAG_ADAPTOR
	uint32_t *owner_32 = (uint32_t *) & (owner_id);

	LOG_KDIAG_ARGS
	    ("partition base: %p, offset: %i, count: %i, black data: %p\n",
	     partition_base, offset_bytes, byte_count, (void *)black_data);
#endif
	(void)user_ctx;

	os_cache_flush_range(black_data, byte_count);

	scc_ret =
	    scc_encrypt_region((uint32_t) partition_base, offset_bytes,
			       byte_count, __virt_to_phys(black_data), IV,
			       cypher_mode);

	if (scc_ret == SCC_RET_OK) {
		retval = FSL_RETURN_OK_S;
	} else {
		retval = FSL_RETURN_ERROR_S;
	}

	/* The SCC2 DMA engine should have written to the black ram, so we need to
	 * invalidate that region of memory.  Note that the red ram is not an
	 * because it is mapped with the cache disabled.
	 */
	os_cache_inv_range(black_data, byte_count);

#else
	(void)scc_ret;
#endif				/* FSL_HAVE_SCC2 */

	return retval;
}
Esempio n. 2
0
static int
do_encrypt_part(scc_part_cipher_access* acc, uint8_t* local_black,
                dma_addr_t black_phys)
{
    int status;
    uint32_t IV[4];
    uint32_t* iv_ptr = (uint32_t*)&(acc->iv);
    
    /* Build the IV */
    IV[0] = iv_ptr[0];
    IV[1] = iv_ptr[1];
    IV[2] = 0;
    IV[3] = 0;

    /* Perform the red -> black encryption */
    acc->scc_status = scc_encrypt_region(acc->virt_address, acc->red_offset,
                                         acc->size_bytes, (void*)black_phys,
                                         IV, SCC_CYPHER_MODE_CBC);

    /* Copy the result to user's memory */
    status = copy_to_user(acc->black_address, local_black, acc->size_bytes);

    return status;
}