diff options
author | Kristina Martšenko <kristina.martsenko@gmail.com> | 2014-07-27 22:59:50 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-27 13:17:47 -0700 |
commit | c22487b828adf09a6ffa3cdf47836d7b4407f827 (patch) | |
tree | 5ba24695e734b88ff53c4e4a5e383fc8fd0c376b /drivers/staging | |
parent | 6b5886f8b2d42de3bfb7764dfafab78fe6777334 (diff) |
staging: sep: remove driver
Looks like no one's working on the driver anymore, so remove it for now.
If someone wants to work on moving it out of staging, this commit can be
reverted.
Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Mark A. Allyn <mark.a.allyn@intel.com>
Cc: Jayant Mangalampalli <jayant.mangalampalli@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/sep/Kconfig | 11 | ||||
-rw-r--r-- | drivers/staging/sep/Makefile | 3 | ||||
-rw-r--r-- | drivers/staging/sep/TODO | 3 | ||||
-rw-r--r-- | drivers/staging/sep/sep_crypto.c | 3979 | ||||
-rw-r--r-- | drivers/staging/sep/sep_crypto.h | 359 | ||||
-rw-r--r-- | drivers/staging/sep/sep_dev.h | 162 | ||||
-rw-r--r-- | drivers/staging/sep/sep_driver_api.h | 402 | ||||
-rw-r--r-- | drivers/staging/sep/sep_driver_config.h | 298 | ||||
-rw-r--r-- | drivers/staging/sep/sep_driver_hw_defs.h | 56 | ||||
-rw-r--r-- | drivers/staging/sep/sep_main.c | 4411 | ||||
-rw-r--r-- | drivers/staging/sep/sep_trace_events.h | 193 |
13 files changed, 0 insertions, 9880 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 90624df0db6f..2c486ea6236b 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -64,8 +64,6 @@ source "drivers/staging/vt6655/Kconfig" source "drivers/staging/vt6656/Kconfig" -source "drivers/staging/sep/Kconfig" - source "drivers/staging/iio/Kconfig" source "drivers/staging/xgifb/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 27f44cdde516..1e1a3a10faf7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_OCTEON_USB) += octeon-usb/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ -obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_USB_EMXX) += emxx_udc/ diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig deleted file mode 100644 index aab945a316ea..000000000000 --- a/drivers/staging/sep/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config DX_SEP - tristate "Discretix SEP driver" - depends on PCI && CRYPTO - help - Discretix SEP driver; used for the security processor subsystem - on board the Intel Mobile Internet Device and adds SEP availability - to the kernel crypto infrastructure - - The driver's name is sep_driver. - - If unsure, select N. diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile deleted file mode 100644 index e48a7959289e..000000000000 --- a/drivers/staging/sep/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -ccflags-y += -I$(srctree)/$(src) -obj-$(CONFIG_DX_SEP) += sep_driver.o -sep_driver-objs := sep_crypto.o sep_main.o diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO deleted file mode 100644 index 3524d0cf84ba..000000000000 --- a/drivers/staging/sep/TODO +++ /dev/null @@ -1,3 +0,0 @@ -Todo's so far (from Alan Cox) -- Clean up unused ioctls -- Clean up unused fields in ioctl structures diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c deleted file mode 100644 index 415322867581..000000000000 --- a/drivers/staging/sep/sep_crypto.c +++ /dev/null @@ -1,3979 +0,0 @@ -/* - * - * sep_crypto.c - Crypto interface structures - * - * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. - * Contributions(c) 2009-2010 Discretix. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * CONTACTS: - * - * Mark Allyn mark.a.allyn@intel.com - * Jayant Mangalampalli jayant.mangalampalli@intel.com - * - * CHANGES: - * - * 2009.06.26 Initial publish - * 2010.09.14 Upgrade to Medfield - * 2011.02.22 Enable Kernel Crypto - * - */ - -/* #define DEBUG */ -#include <linux/module.h> -#include <linux/miscdevice.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/kdev_t.h> -#include <linux/mutex.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/poll.h> -#include <linux/wait.h> -#include <linux/pci.h> -#include <linux/pm_runtime.h> -#include <linux/err.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <linux/workqueue.h> -#include <linux/crypto.h> -#include <crypto/internal/hash.h> -#include <crypto/scatterwalk.h> -#include <crypto/sha.h> -#include <crypto/md5.h> -#include <crypto/aes.h> -#include <crypto/des.h> -#include <crypto/hash.h> -#include "sep_driver_hw_defs.h" -#include "sep_driver_config.h" -#include "sep_driver_api.h" -#include "sep_dev.h" -#include "sep_crypto.h" - -#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) - -/* Globals for queuing */ -static spinlock_t queue_lock; -static struct crypto_queue sep_queue; - -/* Declare of dequeuer */ -static void sep_dequeuer(void *data); - -/* TESTING */ -/** - * sep_do_callback - * @work: pointer to work_struct - * This is what is called by the queue; it is generic so that it - * can be used by any type of operation as each different callback - * function can use the data parameter in its own way - */ -static void sep_do_callback(struct work_struct *work) -{ - struct sep_work_struct *sep_work = container_of(work, - struct sep_work_struct, work); - - if (sep_work != NULL) { - (sep_work->callback)(sep_work->data); - kfree(sep_work); - } else { - pr_debug("sep crypto: do callback - NULL container\n"); - } -} - -/** - * sep_submit_work - * @work_queue: pointer to struct_workqueue - * @funct: pointer to function to execute - * @data: pointer to data; function will know - * how to use it - * This is a generic API to submit something to - * the queue. The callback function will depend - * on what operation is to be done - */ -static int sep_submit_work(struct workqueue_struct *work_queue, - void (*funct)(void *), - void *data) -{ - struct sep_work_struct *sep_work; - int result; - - sep_work = kmalloc(sizeof(struct sep_work_struct), GFP_ATOMIC); - - if (sep_work == NULL) { - pr_debug("sep crypto: cant allocate work structure\n"); - return -ENOMEM; - } - - sep_work->callback = funct; - sep_work->data = data; - INIT_WORK(&sep_work->work, sep_do_callback); - result = queue_work(work_queue, &sep_work->work); - if (!result) { - pr_debug("sep_crypto: queue_work failed\n"); - return -EINVAL; - } - return 0; -} - -/** - * sep_alloc_sg_buf - - * @sep: pointer to struct sep_device - * @size: total size of area - * @block_size: minimum size of chunks - * each page is minimum or modulo this size - * @returns: pointer to struct scatterlist for new - * buffer - **/ -static struct scatterlist *sep_alloc_sg_buf( - struct sep_device *sep, - size_t size, - size_t block_size) -{ - u32 nbr_pages; - u32 ct1; - void *buf; - size_t current_size; - size_t real_page_size; - - struct scatterlist *sg, *sg_temp; - - if (size == 0) - return NULL; - - dev_dbg(&sep->pdev->dev, "sep alloc sg buf\n"); - - current_size = 0; - nbr_pages = 0; - real_page_size = PAGE_SIZE - (PAGE_SIZE % block_size); - /** - * The size of each page must be modulo of the operation - * block size; increment by the modified page size until - * the total size is reached, then you have the number of - * pages - */ - while (current_size < size) { - current_size += real_page_size; - nbr_pages += 1; - } - - sg = kmalloc_array(nbr_pages, sizeof(struct scatterlist), GFP_ATOMIC); - if (!sg) - return NULL; - - sg_init_table(sg, nbr_pages); - - current_size = 0; - sg_temp = sg; - for (ct1 = 0; ct1 < nbr_pages; ct1 += 1) { - buf = (void *)get_zeroed_page(GFP_ATOMIC); - if (!buf) { - dev_warn(&sep->pdev->dev, - "Cannot allocate page for new buffer\n"); - kfree(sg); - return NULL; - } - - sg_set_buf(sg_temp, buf, real_page_size); - if ((size - current_size) > real_page_size) { - sg_temp->length = real_page_size; - current_size += real_page_size; - } else { - sg_temp->length = (size - current_size); - current_size = size; - } - sg_temp = sg_next(sg); - } - return sg; -} - -/** - * sep_free_sg_buf - - * @sg: pointer to struct scatterlist; points to area to free - */ -static void sep_free_sg_buf(struct scatterlist *sg) -{ - struct scatterlist *sg_temp = sg; - while (sg_temp) { - free_page((unsigned long)sg_virt(sg_temp)); - sg_temp = sg_next(sg_temp); - } - kfree(sg); -} - -/** - * sep_copy_sg - - * @sep: pointer to struct sep_device - * @sg_src: pointer to struct scatterlist for source - * @sg_dst: pointer to struct scatterlist for destination - * @size: size (in bytes) of data to copy - * - * Copy data from one scatterlist to another; both must - * be the same size - */ -static void sep_copy_sg( - struct sep_device *sep, - struct scatterlist *sg_src, - struct scatterlist *sg_dst, - size_t size) -{ - u32 seg_size; - u32 in_offset, out_offset; - - u32 count = 0; - struct scatterlist *sg_src_tmp = sg_src; - struct scatterlist *sg_dst_tmp = sg_dst; - - in_offset = 0; - out_offset = 0; - - dev_dbg(&sep->pdev->dev, "sep copy sg\n"); - - if ((sg_src == NULL) || (sg_dst == NULL) || (size == 0)) - return; - - dev_dbg(&sep->pdev->dev, "sep copy sg not null\n"); - - while (count < size) { - if ((sg_src_tmp->length - in_offset) > - (sg_dst_tmp->length - out_offset)) - seg_size = sg_dst_tmp->length - out_offset; - else - seg_size = sg_src_tmp->length - in_offset; - - if (seg_size > (size - count)) - seg_size = (size = count); - - memcpy(sg_virt(sg_dst_tmp) + out_offset, - sg_virt(sg_src_tmp) + in_offset, - seg_size); - - in_offset += seg_size; - out_offset += seg_size; - count += seg_size; - - if (in_offset >= sg_src_tmp->length) { - sg_src_tmp = sg_next(sg_src_tmp); - in_offset = 0; - } - - if (out_offset >= sg_dst_tmp->length) { - sg_dst_tmp = sg_next(sg_dst_tmp); - out_offset = 0; - } - } -} - -/** - * sep_oddball_pages - - * @sep: pointer to struct sep_device - * @sg: pointer to struct scatterlist - buffer to check - * @size: total data size - * @blocksize: minimum block size; must be multiples of this size - * @to_copy: 1 means do copy, 0 means do not copy - * @new_sg: pointer to location to put pointer to new sg area - * @returns: 1 if new scatterlist is needed; 0 if not needed; - * error value if operation failed - * - * The SEP device requires all pages to be multiples of the - * minimum block size appropriate for the operation - * This function check all pages; if any are oddball sizes - * (not multiple of block sizes), it creates a new scatterlist. - * If the to_copy parameter is set to 1, then a scatter list - * copy is performed. The pointer to the new scatterlist is - * put into the address supplied by the new_sg parameter; if - * no new scatterlist is needed, then a NULL is put into - * the location at new_sg. - * - */ -static int sep_oddball_pages( - struct sep_device *sep, - struct scatterlist *sg, - size_t data_size, - u32 block_size, - struct scatterlist **new_sg, - u32 do_copy) -{ - struct scatterlist *sg_temp; - u32 flag; - u32 nbr_pages, page_count; - - dev_dbg(&sep->pdev->dev, "sep oddball\n"); - if ((sg == NULL) || (data_size == 0) || (data_size < block_size)) - return 0; - - dev_dbg(&sep->pdev->dev, "sep oddball not null\n"); - flag = 0; - nbr_pages = 0; - page_count = 0; - sg_temp = sg; - - while (sg_temp) { - nbr_pages += 1; - sg_temp = sg_next(sg_temp); - } - - sg_temp = sg; - while ((sg_temp) && (flag == 0)) { - page_count += 1; - if (sg_temp->length % block_size) - flag = 1; - else - sg_temp = sg_next(sg_temp); - } - - /* Do not process if last (or only) page is oddball */ - if (nbr_pages == page_count) - flag = 0; - - if (flag) { - dev_dbg(&sep->pdev->dev, "sep oddball processing\n"); - *new_sg = sep_alloc_sg_buf(sep, data_size, block_size); - if (*new_sg == NULL) { - dev_warn(&sep->pdev->dev, "cannot allocate new sg\n"); - return -ENOMEM; - } - - if (do_copy) - sep_copy_sg(sep, sg, *new_sg, data_size); - - return 1; - } else { - return 0; - } -} - -/** - * sep_copy_offset_sg - - * @sep: pointer to struct sep_device; - * @sg: pointer to struct scatterlist - * @offset: offset into scatterlist memory - * @dst: place to put data - * @len: length of data - * @returns: number of bytes copies - * - * This copies data from scatterlist buffer - * offset from beginning - it is needed for - * handling tail data in hash - */ -static size_t sep_copy_offset_sg( - struct sep_device *sep, - struct scatterlist *sg, - u32 offset, - void *dst, - u32 len) -{ - size_t page_start; - size_t page_end; - size_t offset_within_page; - size_t length_within_page; - size_t length_remaining; - size_t current_offset; - - /* Find which page is beginning of segment */ - page_start = 0; - page_end = sg->length; - while ((sg) && (offset > page_end)) { - page_start += sg->length; - sg = sg_next(sg); - if (sg) - page_end += sg->length; - } - - if (sg == NULL) - return -ENOMEM; - - offset_within_page = offset - page_start; - if ((sg->length - offset_within_page) >= len) { - /* All within this page */ - memcpy(dst, sg_virt(sg) + offset_within_page, len); - return len; - } else { - /* Scattered multiple pages */ - current_offset = 0; - length_remaining = len; - while ((sg) && (current_offset < len)) { - length_within_page = sg->length - offset_within_page; - if (length_within_page >= length_remaining) { - memcpy(dst+current_offset, - sg_virt(sg) + offset_within_page, - length_remaining); - length_remaining = 0; - current_offset = len; - } else { - memcpy(dst+current_offset, - sg_virt(sg) + offset_within_page, - length_within_page); - length_remaining -= length_within_page; - current_offset += length_within_page; - offset_within_page = 0; - sg = sg_next(sg); - } - } - - if (sg == NULL) - return -ENOMEM; - } - return len; -} - -/** - * partial_overlap - - * @src_ptr: source pointer - * @dst_ptr: destination pointer - * @nbytes: number of bytes - * @returns: 0 for success; -1 for failure - * We cannot have any partial overlap. Total overlap - * where src is the same as dst is okay - */ -static int partial_overlap(void *src_ptr, void *dst_ptr, u32 nbytes) -{ - /* Check for partial overlap */ - if (src_ptr != dst_ptr) { - if (src_ptr < dst_ptr) { - if ((src_ptr + nbytes) > dst_ptr) - return -EINVAL; - } else { - if ((dst_ptr + nbytes) > src_ptr) - return -EINVAL; - } - } - - return 0; -} - -/* Debug - prints only if DEBUG is defined */ -static void sep_dump_ivs(struct ablkcipher_request *req, char *reason) - - { - unsigned char *cptr; - struct sep_aes_internal_context *aes_internal; - struct sep_des_internal_context *des_internal; - int ct1; - - struct this_task_ctx *ta_ctx; - struct crypto_ablkcipher *tfm; - struct sep_system_ctx *sctx; - - ta_ctx = ablkcipher_request_ctx(req); - tfm = crypto_ablkcipher_reqtfm(req); - sctx = crypto_ablkcipher_ctx(tfm); - - dev_dbg(&ta_ctx->sep_used->pdev->dev, "IV DUMP - %s\n", reason); - if ((ta_ctx->current_request == DES_CBC) && - (ta_ctx->des_opmode == SEP_DES_CBC)) { - - des_internal = (struct sep_des_internal_context *) - sctx->des_private_ctx.ctx_buf; - /* print vendor */ - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "sep - vendor iv for DES\n"); - cptr = (unsigned char *)des_internal->iv_context; - for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "%02x\n", *(cptr + ct1)); - - /* print walk */ - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "sep - walk from kernel crypto iv for DES\n"); - cptr = (unsigned char *)ta_ctx->walk.iv; - for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "%02x\n", *(cptr + ct1)); - } else if ((ta_ctx->current_request == AES_CBC) && - (ta_ctx->aes_opmode == SEP_AES_CBC)) { - - aes_internal = (struct sep_aes_internal_context *) - sctx->aes_private_ctx.cbuff; - /* print vendor */ - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "sep - vendor iv for AES\n"); - cptr = (unsigned char *)aes_internal->aes_ctx_iv; - for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "%02x\n", *(cptr + ct1)); - - /* print walk */ - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "sep - walk from kernel crypto iv for AES\n"); - cptr = (unsigned char *)ta_ctx->walk.iv; - for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "%02x\n", *(cptr + ct1)); - } -} - -/** - * RFC2451: Weak key check - * Returns: 1 (weak), 0 (not weak) - */ -static int sep_weak_key(const u8 *key, unsigned int keylen) -{ - static const u8 parity[] = { - 8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8, - 0, 8, 8, 0, 8, 0, 0, 8, 8, - 0, 0, 8, 0, 8, 8, 3, - 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, - 8, 0, 0, 8, 0, 8, 8, 0, 0, - 8, 8, 0, 8, 0, 0, 8, - 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, - 8, 0, 0, 8, 0, 8, 8, 0, 0, - 8, 8, 0, 8, 0, 0, 8, - 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, - 0, 8, 8, 0, 8, 0, 0, 8, 8, - 0, 0, 8, 0, 8, 8, 0, - 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, - 8, 0, 0, 8, 0, 8, 8, 0, 0, - 8, 8, 0, 8, 0, 0, 8, - 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, - 0, 8, 8, 0, 8, 0, 0, 8, 8, - 0, 0, 8, 0, 8, 8, 0, - 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, - 0, 8, 8, 0, 8, 0, 0, 8, 8, - 0, 0, 8, 0, 8, 8, 0, - 4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, - 8, 5, 0, 8, 0, 8, 8, 0, 0, - 8, 8, 0, 8, 0, 6, 8, - }; - - u32 n, w; - - n = parity[key[0]]; n <<= 4; - n |= parity[key[1]]; n <<= 4; - n |= parity[key[2]]; n <<= 4; - n |= parity[key[3]]; n <<= 4; - n |= parity[key[4]]; n <<= 4; - n |= parity[key[5]]; n <<= 4; - n |= parity[key[6]]; n <<= 4; - n |= parity[key[7]]; - w = 0x88888888L; - - /* 1 in 10^10 keys passes this test */ - if (!((n - (w >> 3)) & w)) { - if (n < 0x41415151) { - if (n < 0x31312121) { - if (n < 0x14141515) { - /* 01 01 01 01 01 01 01 01 */ - if (n == 0x11111111) - goto weak; - /* 01 1F 01 1F 01 0E 01 0E */ - if (n == 0x13131212) - goto weak; - } else { - /* 01 E0 01 E0 01 F1 01 F1 */ - if (n == 0x14141515) - goto weak; - /* 01 FE 01 FE 01 FE 01 FE */ - if (n == 0x16161616) - goto weak; - } - } else { - if (n < 0x34342525) { - /* 1F 01 1F 01 0E 01 0E 01 */ - if (n == 0x31312121) - goto weak; - /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ - if (n == 0x33332222) - goto weak; - } else { - /* 1F E0 1F E0 0E F1 0E F1 */ - if (n == 0x34342525) - goto weak; - /* 1F FE 1F FE 0E FE 0E FE */ - if (n == 0x36362626) - goto weak; - } - } - } else { - if (n < 0x61616161) { - if (n < 0x44445555) { - /* E0 01 E0 01 F1 01 F1 01 */ - if (n == 0x41415151) - goto weak; - /* E0 1F E0 1F F1 0E F1 0E */ - if (n == 0x43435252) - goto weak; - } else { - /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ - if (n == 0x44445555) - goto weak; - /* E0 FE E0 FE F1 FE F1 FE */ - if (n == 0x46465656) - goto weak; - } - } else { - if (n < 0x64646565) { - /* FE 01 FE 01 FE 01 FE 01 */ - if (n == 0x61616161) - goto weak; - /* FE 1F FE 1F FE 0E FE 0E */ - if (n == 0x63636262) - goto weak; - } else { - /* FE E0 FE E0 FE F1 FE F1 */ - if (n == 0x64646565) - goto weak; - /* FE FE FE FE FE FE FE FE */ - if (n == 0x66666666) - goto weak; - } - } - } - } - return 0; -weak: - return 1; -} -/** - * sep_sg_nents - */ -static u32 sep_sg_nents(struct scatterlist *sg) -{ - u32 ct1 = 0; - - while (sg) { - ct1 += 1; - sg = sg_next(sg); - } - - return ct1; -} - -/** - * sep_start_msg - - * @ta_ctx: pointer to struct this_task_ctx - * @returns: offset to place for the next word in the message - * Set up pointer in message pool for new message - */ -static u32 sep_start_msg(struct this_task_ctx *ta_ctx) -{ - u32 *word_ptr; - - ta_ctx->msg_len_words = 2; - ta_ctx->msgptr = ta_ctx->msg; - memset(ta_ctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - ta_ctx->msgptr += sizeof(u32) * 2; - word_ptr = (u32 *)ta_ctx->msgptr; - *word_ptr = SEP_START_MSG_TOKEN; - return sizeof(u32) * 2; -} - -/** - * sep_end_msg - - * @ta_ctx: pointer to struct this_task_ctx - * @messages_offset: current message offset - * Returns: 0 for success; <0 otherwise - * End message; set length and CRC; and - * send interrupt to the SEP - */ -static void sep_end_msg(struct this_task_ctx *ta_ctx, u32 msg_offset) -{ - u32 *word_ptr; - /* Msg size goes into msg after token */ - ta_ctx->msg_len_words = msg_offset / sizeof(u32) + 1; - word_ptr = (u32 *)ta_ctx->msgptr; - word_ptr += 1; - *word_ptr = ta_ctx->msg_len_words; - - /* CRC (currently 0) goes at end of msg */ - word_ptr = (u32 *)(ta_ctx->msgptr + msg_offset); - *word_ptr = 0; -} - -/** - * sep_start_inbound_msg - - * @ta_ctx: pointer to struct this_task_ctx - * @msg_offset: offset to place for the next word in the message - * @returns: 0 for success; error value for failure - * Set up pointer in message pool for inbound message - */ -static u32 sep_start_inbound_msg(struct this_task_ctx *ta_ctx, u32 *msg_offset) -{ - u32 *word_ptr; - u32 token; - u32 error = SEP_OK; - - *msg_offset = sizeof(u32) * 2; - word_ptr = (u32 *)ta_ctx->msgptr; - token = *word_ptr; - ta_ctx->msg_len_words = *(word_ptr + 1); - - if (token != SEP_START_MSG_TOKEN) { - error = SEP_INVALID_START; - goto end_function; - } - -end_function: - - return error; -} - -/** - * sep_write_msg - - * @ta_ctx: pointer to struct this_task_ctx - * @in_addr: pointer to start of parameter - * @size: size of parameter to copy (in bytes) - * @max_size: size to move up offset; SEP mesg is in word sizes - * @msg_offset: pointer to current offset (is updated) - * @byte_array: flag ti indicate whether endian must be changed - * Copies data into the message area from caller - */ -static void sep_write_msg(struct this_task_ctx *ta_ctx, void *in_addr, - u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) -{ - u32 *word_ptr; - void *void_ptr; - - void_ptr = ta_ctx->msgptr + *msg_offset; - word_ptr = (u32 *)void_ptr; - memcpy(void_ptr, in_addr, size); - *msg_offset += max_size; - - /* Do we need to manipulate endian? */ - if (byte_array) { - u32 i; - - for (i = 0; i < ((size + 3) / 4); i += 1) - *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); - } -} - -/** - * sep_make_header - * @ta_ctx: pointer to struct this_task_ctx - * @msg_offset: pointer to current offset (is updated) - * @op_code: op code to put into message - * Puts op code into message and updates offset - */ -static void sep_make_header(struct this_task_ctx *ta_ctx, u32 *msg_offset, - u32 op_code) -{ - u32 *word_ptr; - - *msg_offset = sep_start_msg(ta_ctx); - word_ptr = (u32 *)(ta_ctx->msgptr + *msg_offset); - *word_ptr = op_code; - *msg_offset += sizeof(u32); -} - - - -/** - * sep_read_msg - - * @ta_ctx: pointer to struct this_task_ctx - * @in_addr: pointer to start of parameter - * @size: size of parameter to copy (in bytes) - * @max_size: size to move up offset; SEP mesg is in word sizes - * @msg_offset: pointer to current offset (is updated) - * @byte_array: flag ti indicate whether endian must be changed - * Copies data out of the message area to caller - */ -static void sep_read_msg(struct this_task_ctx *ta_ctx, void *in_addr, - u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) -{ - u32 *word_ptr; - void *void_ptr; - - void_ptr = ta_ctx->msgptr + *msg_offset; - word_ptr = (u32 *)void_ptr; - - /* Do we need to manipulate endian? */ - if (byte_array) { - u32 i; - - for (i = 0; i < ((size + 3) / 4); i += 1) - *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); - } - - memcpy(in_addr, void_ptr, size); - *msg_offset += max_size; -} - -/** - * sep_verify_op - - * @ta_ctx: pointer to struct this_task_ctx - * @op_code: expected op_code - * @msg_offset: pointer to current offset (is updated) - * @returns: 0 for success; error for failure - */ -static u32 sep_verify_op(struct this_task_ctx *ta_ctx, u32 op_code, - u32 *msg_offset) -{ - u32 error; - u32 in_ary[2]; - - struct sep_device *sep = ta_ctx->sep_used; - - dev_dbg(&sep->pdev->dev, "dumping return message\n"); - error = sep_start_inbound_msg(ta_ctx, msg_offset); - if (error) { - dev_warn(&sep->pdev->dev, - "sep_start_inbound_msg error\n"); - return error; - } - - sep_read_msg(ta_ctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2, - msg_offset, 0); - - if (in_ary[0] != op_code) { - dev_warn(&sep->pdev->dev, - "sep got back wrong opcode\n"); - dev_warn(&sep->pdev->dev, - "got back %x; expected %x\n", - in_ary[0], op_code); - return SEP_WRONG_OPCODE; - } - - if (in_ary[1] != SEP_OK) { - dev_warn(&sep->pdev->dev, - "sep execution error\n"); - dev_warn(&sep->pdev->dev, - "got back %x; expected %x\n", - in_ary[1], SEP_OK); - return in_ary[0]; - } - -return 0; -} - -/** - * sep_read_context - - * @ta_ctx: pointer to struct this_task_ctx - * @msg_offset: point to current place in SEP msg; is updated - * @dst: pointer to place to put the context - * @len: size of the context structure (differs for crypro/hash) - * This function reads the context from the msg area - * There is a special way the vendor needs to have the maximum - * length calculated so that the msg_offset is updated properly; - * it skips over some words in the msg area depending on the size - * of the context - */ -static void sep_read_context(struct this_task_ctx *ta_ctx, u32 *msg_offset, - void *dst, u32 len) -{ - u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); - - sep_read_msg(ta_ctx, dst, len, max_length, msg_offset, 0); -} - -/** - * sep_write_context - - * @ta_ctx: pointer to struct this_task_ctx - * @msg_offset: point to current place in SEP msg; is updated - * @src: pointer to the current context - * @len: size of the context structure (differs for crypro/hash) - * This function writes the context to the msg area - * There is a special way the vendor needs to have the maximum - * length calculated so that the msg_offset is updated properly; - * it skips over some words in the msg area depending on the size - * of the context - */ -static void sep_write_context(struct this_task_ctx *ta_ctx, u32 *msg_offset, - void *src, u32 len) -{ - u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); - - sep_write_msg(ta_ctx, src, len, max_length, msg_offset, 0); -} - -/** - * sep_clear_out - - * @ta_ctx: pointer to struct this_task_ctx - * Clear out crypto related values in sep device structure - * to enable device to be used by anyone; either kernel - * crypto or userspace app via middleware - */ -static void sep_clear_out(struct this_task_ctx *ta_ctx) -{ - if (ta_ctx->src_sg_hold) { - sep_free_sg_buf(ta_ctx->src_sg_hold); - ta_ctx->src_sg_hold = NULL; - } - - if (ta_ctx->dst_sg_hold) { - sep_free_sg_buf(ta_ctx->dst_sg_hold); - ta_ctx->dst_sg_hold = NULL; - } - - ta_ctx->src_sg = NULL; - ta_ctx->dst_sg = NULL; - - sep_free_dma_table_data_handler(ta_ctx->sep_used, &ta_ctx->dma_ctx); - - if (ta_ctx->i_own_sep) { - /** - * The following unlocks the sep and makes it available - * to any other application - * First, null out crypto entries in sep before releasing it - */ - ta_ctx->sep_used->current_hash_req = NULL; - ta_ctx->sep_used->current_cypher_req = NULL; - ta_ctx->sep_used->current_request = 0; - ta_ctx->sep_used->current_hash_stage = 0; - ta_ctx->sep_used->ta_ctx = NULL; - ta_ctx->sep_used->in_kernel = 0; - - ta_ctx->call_status.status = 0; - - /* Remove anything confidential */ - memset(ta_ctx->sep_used->shared_addr, 0, - SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - - sep_queue_status_remove(ta_ctx->sep_used, &ta_ctx->queue_elem); - -#ifdef SEP_ENABLE_RUNTIME_PM - ta_ctx->sep_used->in_use = 0; - pm_runtime_mark_last_busy(&ta_ctx->sep_used->pdev->dev); - pm_runtime_put_autosuspend(&ta_ctx->sep_used->pdev->dev); -#endif - - clear_bit(SEP_WORKING_LOCK_BIT, - &ta_ctx->sep_used->in_use_flags); - ta_ctx->sep_used->pid_doing_transaction = 0; - - dev_dbg(&ta_ctx->sep_used->pdev->dev, - "[PID%d] waking up next transaction\n", - current->pid); - - clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, - &ta_ctx->sep_used->in_use_flags); - wake_up(&ta_ctx->sep_used->event_transactions); - - ta_ctx->i_own_sep = 0; - } -} - -/** - * Release crypto infrastructure from EINPROGRESS and - * clear sep_dev so that SEP is available to anyone - */ -static void sep_crypto_release(struct sep_system_ctx *sctx, - struct this_task_ctx *ta_ctx, u32 error) -{ - struct ahash_request *hash_req = ta_ctx->current_hash_req; - struct ablkcipher_request *cypher_req = - ta_ctx->current_cypher_req; - struct sep_device *sep = ta_ctx->sep_used; - - sep_clear_out(ta_ctx); - - /** - * This may not yet exist depending when we - * chose to bail out. If it does exist, set - * it to 1 - */ - if (ta_ctx->are_we_done_yet != NULL) - *ta_ctx->are_we_done_yet = 1; - - if (cypher_req != NULL) { - if ((sctx->key_sent == 1) || - ((error != 0) && (error != -EINPROGRESS))) { - if (cypher_req->base.complete == NULL) { - dev_dbg(&sep->pdev->dev, - "release is null for cypher!"); - |