/* * 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; }
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; }