|
@@ -88,17 +88,17 @@ static void sep_dequeuer(void *data);
|
|
|
* This will only print dump if DEBUG is set; it does
|
|
|
* follow kernel debug print enabling
|
|
|
*/
|
|
|
-static void crypto_sep_dump_message(struct sep_system_ctx *sctx)
|
|
|
+static void crypto_sep_dump_message(struct sep_device *sep, void *msg)
|
|
|
{
|
|
|
#if 0
|
|
|
u32 *p;
|
|
|
u32 *i;
|
|
|
int count;
|
|
|
|
|
|
- p = sctx->sep_used->shared_addr;
|
|
|
- i = (u32 *)sctx->msg;
|
|
|
- for (count = 0; count < 40 * 4; count += 4)
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ p = sep->shared_addr;
|
|
|
+ i = (u32 *)msg;
|
|
|
+ for (count = 0; count < 10 * 4; count += 4)
|
|
|
+ dev_dbg(&sep->pdev->dev,
|
|
|
"[PID%d] Word %d of the message is %x (local)%x\n",
|
|
|
current->pid, count/4, *p++, *i++);
|
|
|
#endif
|
|
@@ -534,6 +534,67 @@ static void sep_dump_sg(struct sep_device *sep, char *stg,
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+/* 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)
|
|
@@ -671,61 +732,61 @@ static u32 sep_sg_nents(struct scatterlist *sg)
|
|
|
|
|
|
/**
|
|
|
* sep_start_msg -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx)
|
|
|
+static u32 sep_start_msg(struct this_task_ctx *ta_ctx)
|
|
|
{
|
|
|
u32 *word_ptr;
|
|
|
- sctx->msg_len_words = 2;
|
|
|
- sctx->msgptr = sctx->msg;
|
|
|
- memset(sctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
- sctx->msgptr += sizeof(u32) * 2;
|
|
|
- word_ptr = (u32 *)sctx->msgptr;
|
|
|
+ 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 -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx, u32 msg_offset)
|
|
|
+static void sep_end_msg(struct this_task_ctx *ta_ctx, u32 msg_offset)
|
|
|
{
|
|
|
u32 *word_ptr;
|
|
|
/* Msg size goes into msg after token */
|
|
|
- sctx->msg_len_words = msg_offset / sizeof(u32) + 1;
|
|
|
- word_ptr = (u32 *)sctx->msgptr;
|
|
|
+ ta_ctx->msg_len_words = msg_offset / sizeof(u32) + 1;
|
|
|
+ word_ptr = (u32 *)ta_ctx->msgptr;
|
|
|
word_ptr += 1;
|
|
|
- *word_ptr = sctx->msg_len_words;
|
|
|
+ *word_ptr = ta_ctx->msg_len_words;
|
|
|
|
|
|
/* CRC (currently 0) goes at end of msg */
|
|
|
- word_ptr = (u32 *)(sctx->msgptr + msg_offset);
|
|
|
+ word_ptr = (u32 *)(ta_ctx->msgptr + msg_offset);
|
|
|
*word_ptr = 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* sep_start_inbound_msg -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx, u32 *msg_offset)
|
|
|
+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 *)sctx->msgptr;
|
|
|
+ word_ptr = (u32 *)ta_ctx->msgptr;
|
|
|
token = *word_ptr;
|
|
|
- sctx->msg_len_words = *(word_ptr + 1);
|
|
|
+ ta_ctx->msg_len_words = *(word_ptr + 1);
|
|
|
|
|
|
if (token != SEP_START_MSG_TOKEN) {
|
|
|
error = SEP_INVALID_START;
|
|
@@ -739,7 +800,7 @@ end_function:
|
|
|
|
|
|
/**
|
|
|
* sep_write_msg -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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
|
|
@@ -747,12 +808,12 @@ end_function:
|
|
|
* @byte_array: flag ti indicate wheter endian must be changed
|
|
|
* Copies data into the message area from caller
|
|
|
*/
|
|
|
-static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr,
|
|
|
+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 = sctx->msgptr + *msg_offset;
|
|
|
+ void_ptr = ta_ctx->msgptr + *msg_offset;
|
|
|
word_ptr = (u32 *)void_ptr;
|
|
|
memcpy(void_ptr, in_addr, size);
|
|
|
*msg_offset += max_size;
|
|
@@ -767,18 +828,18 @@ static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr,
|
|
|
|
|
|
/**
|
|
|
* sep_make_header
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx, u32 *msg_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(sctx);
|
|
|
- word_ptr = (u32 *)(sctx->msgptr + *msg_offset);
|
|
|
+ *msg_offset = sep_start_msg(ta_ctx);
|
|
|
+ word_ptr = (u32 *)(ta_ctx->msgptr + *msg_offset);
|
|
|
*word_ptr = op_code;
|
|
|
*msg_offset += sizeof(u32);
|
|
|
}
|
|
@@ -787,7 +848,7 @@ static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset,
|
|
|
|
|
|
/**
|
|
|
* sep_read_msg -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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
|
|
@@ -795,12 +856,12 @@ static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset,
|
|
|
* @byte_array: flag ti indicate wheter endian must be changed
|
|
|
* Copies data out of the message area to caller
|
|
|
*/
|
|
|
-static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr,
|
|
|
+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 = sctx->msgptr + *msg_offset;
|
|
|
+ void_ptr = ta_ctx->msgptr + *msg_offset;
|
|
|
word_ptr = (u32 *)void_ptr;
|
|
|
|
|
|
/* Do we need to manipulate endian? */
|
|
@@ -816,28 +877,28 @@ static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr,
|
|
|
|
|
|
/**
|
|
|
* sep_verify_op -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx, u32 op_code,
|
|
|
+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 = sctx->sep_used;
|
|
|
+ struct sep_device *sep = ta_ctx->sep_used;
|
|
|
|
|
|
dev_dbg(&sep->pdev->dev, "dumping return message\n");
|
|
|
- error = sep_start_inbound_msg(sctx, msg_offset);
|
|
|
+ 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(sctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2,
|
|
|
+ sep_read_msg(ta_ctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2,
|
|
|
msg_offset, 0);
|
|
|
|
|
|
if (in_ary[0] != op_code) {
|
|
@@ -863,7 +924,7 @@ return 0;
|
|
|
|
|
|
/**
|
|
|
* sep_read_context -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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)
|
|
@@ -873,16 +934,16 @@ return 0;
|
|
|
* it skips over some words in the msg area depending on the size
|
|
|
* of the context
|
|
|
*/
|
|
|
-static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset,
|
|
|
+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(sctx, dst, len, max_length, msg_offset, 0);
|
|
|
+ sep_read_msg(ta_ctx, dst, len, max_length, msg_offset, 0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* sep_write_context -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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)
|
|
@@ -892,76 +953,77 @@ static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset,
|
|
|
* it skips over some words in the msg area depending on the size
|
|
|
* of the context
|
|
|
*/
|
|
|
-static void sep_write_context(struct sep_system_ctx *sctx, u32 *msg_offset,
|
|
|
+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(sctx, src, len, max_length, msg_offset, 0);
|
|
|
+ sep_write_msg(ta_ctx, src, len, max_length, msg_offset, 0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* sep_clear_out -
|
|
|
- * @sctx: pointer to struct sep_system_ctx
|
|
|
+ * @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 sep_system_ctx *sctx)
|
|
|
+static void sep_clear_out(struct this_task_ctx *ta_ctx)
|
|
|
{
|
|
|
- if (sctx->src_sg_hold) {
|
|
|
- sep_free_sg_buf(sctx->src_sg_hold);
|
|
|
- sctx->src_sg_hold = NULL;
|
|
|
+ if (ta_ctx->src_sg_hold) {
|
|
|
+ sep_free_sg_buf(ta_ctx->src_sg_hold);
|
|
|
+ ta_ctx->src_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- if (sctx->dst_sg_hold) {
|
|
|
- sep_free_sg_buf(sctx->dst_sg_hold);
|
|
|
- sctx->dst_sg_hold = NULL;
|
|
|
+ if (ta_ctx->dst_sg_hold) {
|
|
|
+ sep_free_sg_buf(ta_ctx->dst_sg_hold);
|
|
|
+ ta_ctx->dst_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- sctx->src_sg = NULL;
|
|
|
- sctx->dst_sg = NULL;
|
|
|
+ ta_ctx->src_sg = NULL;
|
|
|
+ ta_ctx->dst_sg = NULL;
|
|
|
|
|
|
- sep_free_dma_table_data_handler(sctx->sep_used, &sctx->dma_ctx);
|
|
|
+ sep_free_dma_table_data_handler(ta_ctx->sep_used, &ta_ctx->dma_ctx);
|
|
|
|
|
|
- if (sctx->i_own_sep) {
|
|
|
+ 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 relesing it
|
|
|
*/
|
|
|
- sctx->sep_used->current_hash_req = NULL;
|
|
|
- sctx->sep_used->current_cypher_req = NULL;
|
|
|
- sctx->sep_used->current_request = 0;
|
|
|
- sctx->sep_used->current_hash_stage = 0;
|
|
|
- sctx->sep_used->sctx = NULL;
|
|
|
- sctx->sep_used->in_kernel = 0;
|
|
|
+ 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;
|
|
|
|
|
|
- sctx->call_status.status = 0;
|
|
|
+ ta_ctx->call_status.status = 0;
|
|
|
|
|
|
/* Remove anything confidentail */
|
|
|
- memset(sctx->sep_used->shared_addr, 0,
|
|
|
+ memset(ta_ctx->sep_used->shared_addr, 0,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
- sep_queue_status_remove(sctx->sep_used, &sctx->queue_elem);
|
|
|
+ sep_queue_status_remove(ta_ctx->sep_used, &ta_ctx->queue_elem);
|
|
|
|
|
|
#ifdef SEP_ENABLE_RUNTIME_PM
|
|
|
- sctx->sep_used->in_use = 0;
|
|
|
- pm_runtime_mark_last_busy(&sctx->sep_used->pdev->dev);
|
|
|
- pm_runtime_put_autosuspend(&sctx->sep_used->pdev->dev);
|
|
|
+ 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, &sctx->sep_used->in_use_flags);
|
|
|
- sctx->sep_used->pid_doing_transaction = 0;
|
|
|
+ clear_bit(SEP_WORKING_LOCK_BIT,
|
|
|
+ &ta_ctx->sep_used->in_use_flags);
|
|
|
+ ta_ctx->sep_used->pid_doing_transaction = 0;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"[PID%d] waking up next transaction\n",
|
|
|
current->pid);
|
|
|
|
|
|
clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
|
|
|
- &sctx->sep_used->in_use_flags);
|
|
|
- wake_up(&sctx->sep_used->event_transactions);
|
|
|
+ &ta_ctx->sep_used->in_use_flags);
|
|
|
+ wake_up(&ta_ctx->sep_used->event_transactions);
|
|
|
|
|
|
- sctx->i_own_sep = 0;
|
|
|
+ ta_ctx->i_own_sep = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -969,22 +1031,34 @@ static void sep_clear_out(struct sep_system_ctx *sctx)
|
|
|
* 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, u32 error)
|
|
|
+static void sep_crypto_release(struct sep_system_ctx *sctx,
|
|
|
+ struct this_task_ctx *ta_ctx, u32 error)
|
|
|
{
|
|
|
- struct ahash_request *hash_req = sctx->current_hash_req;
|
|
|
+ struct ahash_request *hash_req = ta_ctx->current_hash_req;
|
|
|
struct ablkcipher_request *cypher_req =
|
|
|
- sctx->current_cypher_req;
|
|
|
- struct sep_device *sep = sctx->sep_used;
|
|
|
+ ta_ctx->current_cypher_req;
|
|
|
+ struct sep_device *sep = ta_ctx->sep_used;
|
|
|
+
|
|
|
+ sep_clear_out(ta_ctx);
|
|
|
|
|
|
- sep_clear_out(sctx);
|
|
|
+ /**
|
|
|
+ * 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 (cypher_req->base.complete == NULL) {
|
|
|
- dev_dbg(&sep->pdev->dev,
|
|
|
- "release is null for cypher!");
|
|
|
- } else {
|
|
|
- cypher_req->base.complete(
|
|
|
- &cypher_req->base, error);
|
|
|
+ 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!");
|
|
|
+ } else {
|
|
|
+ cypher_req->base.complete(
|
|
|
+ &cypher_req->base, error);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1005,20 +1079,20 @@ static void sep_crypto_release(struct sep_system_ctx *sctx, u32 error)
|
|
|
* and it will return 0 if sep is now ours; error value if there
|
|
|
* were problems
|
|
|
*/
|
|
|
-static int sep_crypto_take_sep(struct sep_system_ctx *sctx)
|
|
|
+static int sep_crypto_take_sep(struct this_task_ctx *ta_ctx)
|
|
|
{
|
|
|
- struct sep_device *sep = sctx->sep_used;
|
|
|
+ struct sep_device *sep = ta_ctx->sep_used;
|
|
|
int result;
|
|
|
struct sep_msgarea_hdr *my_msg_header;
|
|
|
|
|
|
- my_msg_header = (struct sep_msgarea_hdr *)sctx->msg;
|
|
|
+ my_msg_header = (struct sep_msgarea_hdr *)ta_ctx->msg;
|
|
|
|
|
|
/* add to status queue */
|
|
|
- sctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode,
|
|
|
- sctx->nbytes, current->pid,
|
|
|
+ ta_ctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode,
|
|
|
+ ta_ctx->nbytes, current->pid,
|
|
|
current->comm, sizeof(current->comm));
|
|
|
|
|
|
- if (!sctx->queue_elem) {
|
|
|
+ if (!ta_ctx->queue_elem) {
|
|
|
dev_dbg(&sep->pdev->dev, "[PID%d] updating queue"
|
|
|
" status error\n", current->pid);
|
|
|
return -EINVAL;
|
|
@@ -1033,48 +1107,61 @@ static int sep_crypto_take_sep(struct sep_system_ctx *sctx)
|
|
|
pm_runtime_get_sync(&sep_dev->pdev->dev);
|
|
|
|
|
|
/* Copy in the message */
|
|
|
- memcpy(sep->shared_addr, sctx->msg,
|
|
|
+ memcpy(sep->shared_addr, ta_ctx->msg,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
/* Copy in the dcb information if there is any */
|
|
|
- if (sctx->dcb_region) {
|
|
|
+ if (ta_ctx->dcb_region) {
|
|
|
result = sep_activate_dcb_dmatables_context(sep,
|
|
|
- &sctx->dcb_region, &sctx->dmatables_region,
|
|
|
- sctx->dma_ctx);
|
|
|
+ &ta_ctx->dcb_region, &ta_ctx->dmatables_region,
|
|
|
+ ta_ctx->dma_ctx);
|
|
|
if (result)
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/* Mark the device so we know how to finish the job in the tasklet */
|
|
|
- if (sctx->current_hash_req)
|
|
|
- sep->current_hash_req = sctx->current_hash_req;
|
|
|
+ if (ta_ctx->current_hash_req)
|
|
|
+ sep->current_hash_req = ta_ctx->current_hash_req;
|
|
|
else
|
|
|
- sep->current_cypher_req = sctx->current_cypher_req;
|
|
|
+ sep->current_cypher_req = ta_ctx->current_cypher_req;
|
|
|
|
|
|
- sep->current_request = sctx->current_request;
|
|
|
- sep->current_hash_stage = sctx->current_hash_stage;
|
|
|
- sep->sctx = sctx;
|
|
|
+ sep->current_request = ta_ctx->current_request;
|
|
|
+ sep->current_hash_stage = ta_ctx->current_hash_stage;
|
|
|
+ sep->ta_ctx = ta_ctx;
|
|
|
sep->in_kernel = 1;
|
|
|
- sctx->i_own_sep = 1;
|
|
|
+ ta_ctx->i_own_sep = 1;
|
|
|
+
|
|
|
+ /* need to set bit first to avoid race condition with interrupt */
|
|
|
+ set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &ta_ctx->call_status.status);
|
|
|
|
|
|
result = sep_send_command_handler(sep);
|
|
|
|
|
|
dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n",
|
|
|
current->pid);
|
|
|
|
|
|
- if (!result) {
|
|
|
- set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
|
|
|
- &sctx->call_status.status);
|
|
|
+ if (!result)
|
|
|
dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n",
|
|
|
current->pid);
|
|
|
+ else {
|
|
|
+ dev_dbg(&sep->pdev->dev, "[PID%d]: cant send command\n",
|
|
|
+ current->pid);
|
|
|
+ clear_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
|
|
|
+ &ta_ctx->call_status.status);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-/* This needs to be run as a work queue as it can be put asleep */
|
|
|
-static void sep_crypto_block(void *data)
|
|
|
+/**
|
|
|
+ * This function sets things up for a crypto data block process
|
|
|
+ * This does all preparation, but does not try to grab the
|
|
|
+ * sep
|
|
|
+ * @req: pointer to struct ablkcipher_request
|
|
|
+ * returns: 0 if all went well, non zero if error
|
|
|
+ */
|
|
|
+static int sep_crypto_block_data(struct ablkcipher_request *req)
|
|
|
{
|
|
|
+
|
|
|
int int_error;
|
|
|
u32 msg_offset;
|
|
|
static u32 msg[10];
|
|
@@ -1085,318 +1172,440 @@ static void sep_crypto_block(void *data)
|
|
|
ssize_t copy_result;
|
|
|
int result;
|
|
|
|
|
|
- u32 max_length;
|
|
|
struct scatterlist *new_sg;
|
|
|
- struct ablkcipher_request *req;
|
|
|
- struct sep_block_ctx *bctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct crypto_ablkcipher *tfm;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
|
|
|
- req = (struct ablkcipher_request *)data;
|
|
|
- bctx = ablkcipher_request_ctx(req);
|
|
|
+ struct sep_des_internal_context *des_internal;
|
|
|
+ struct sep_aes_internal_context *aes_internal;
|
|
|
+
|
|
|
+ ta_ctx = ablkcipher_request_ctx(req);
|
|
|
tfm = crypto_ablkcipher_reqtfm(req);
|
|
|
sctx = crypto_ablkcipher_ctx(tfm);
|
|
|
|
|
|
/* start the walk on scatterlists */
|
|
|
- ablkcipher_walk_init(&bctx->walk, req->src, req->dst, req->nbytes);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep crypto block data size of %x\n",
|
|
|
+ ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep crypto block data size of %x\n",
|
|
|
req->nbytes);
|
|
|
|
|
|
- int_error = ablkcipher_walk_phys(req, &bctx->walk);
|
|
|
+ int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
|
|
|
if (int_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n",
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
|
|
|
int_error);
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* check iv */
|
|
|
- if (bctx->des_opmode == SEP_DES_CBC) {
|
|
|
- if (!bctx->walk.iv) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- memcpy(bctx->iv, bctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
- sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
- }
|
|
|
-
|
|
|
- if (bctx->aes_opmode == SEP_AES_CBC) {
|
|
|
- if (!bctx->walk.iv) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- memcpy(bctx->iv, bctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
- sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"crypto block: src is %lx dst is %lx\n",
|
|
|
(unsigned long)req->src, (unsigned long)req->dst);
|
|
|
|
|
|
/* Make sure all pages are even block */
|
|
|
- int_error = sep_oddball_pages(sctx->sep_used, req->src,
|
|
|
- req->nbytes, bctx->walk.blocksize, &new_sg, 1);
|
|
|
+ int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
|
|
|
+ req->nbytes, ta_ctx->walk.blocksize, &new_sg, 1);
|
|
|
|
|
|
if (int_error < 0) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "oddball page eerror\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
- return;
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page eerror\n");
|
|
|
+ return -ENOMEM;
|
|
|
} else if (int_error == 1) {
|
|
|
- sctx->src_sg = new_sg;
|
|
|
- sctx->src_sg_hold = new_sg;
|
|
|
+ ta_ctx->src_sg = new_sg;
|
|
|
+ ta_ctx->src_sg_hold = new_sg;
|
|
|
} else {
|
|
|
- sctx->src_sg = req->src;
|
|
|
- sctx->src_sg_hold = NULL;
|
|
|
+ ta_ctx->src_sg = req->src;
|
|
|
+ ta_ctx->src_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- int_error = sep_oddball_pages(sctx->sep_used, req->dst,
|
|
|
- req->nbytes, bctx->walk.blocksize, &new_sg, 0);
|
|
|
+ int_error = sep_oddball_pages(ta_ctx->sep_used, req->dst,
|
|
|
+ req->nbytes, ta_ctx->walk.blocksize, &new_sg, 0);
|
|
|
|
|
|
if (int_error < 0) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n",
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
|
|
|
int_error);
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
- return;
|
|
|
+ return -ENOMEM;
|
|
|
} else if (int_error == 1) {
|
|
|
- sctx->dst_sg = new_sg;
|
|
|
- sctx->dst_sg_hold = new_sg;
|
|
|
+ ta_ctx->dst_sg = new_sg;
|
|
|
+ ta_ctx->dst_sg_hold = new_sg;
|
|
|
} else {
|
|
|
- sctx->dst_sg = req->dst;
|
|
|
- sctx->dst_sg_hold = NULL;
|
|
|
+ ta_ctx->dst_sg = req->dst;
|
|
|
+ ta_ctx->dst_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- /* Do we need to perform init; ie; send key to sep? */
|
|
|
- if (sctx->key_sent == 0) {
|
|
|
+ /* set nbytes for queue status */
|
|
|
+ ta_ctx->nbytes = req->nbytes;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sending key\n");
|
|
|
+ /* Key already done; this is for data */
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending data\n");
|
|
|
|
|
|
- /* put together message to SEP */
|
|
|
- /* Start with op code */
|
|
|
- sep_make_header(sctx, &msg_offset, bctx->init_opcode);
|
|
|
+ sep_dump_sg(ta_ctx->sep_used,
|
|
|
+ "block sg in", ta_ctx->src_sg);
|
|
|
|
|
|
- /* now deal with IV */
|
|
|
- if (bctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
- if (bctx->des_opmode == SEP_DES_CBC) {
|
|
|
- sep_write_msg(sctx, bctx->iv,
|
|
|
- SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4,
|
|
|
- &msg_offset, 1);
|
|
|
- sep_dump(sctx->sep_used, "initial IV",
|
|
|
- bctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
- } else {
|
|
|
- /* Skip if ECB */
|
|
|
- msg_offset += 4 * sizeof(u32);
|
|
|
- }
|
|
|
- } else {
|
|
|
- max_length = ((SEP_AES_IV_SIZE_BYTES + 3) /
|
|
|
- sizeof(u32)) * sizeof(u32);
|
|
|
- if (bctx->aes_opmode == SEP_AES_CBC) {
|
|
|
- sep_write_msg(sctx, bctx->iv,
|
|
|
- SEP_AES_IV_SIZE_BYTES, max_length,
|
|
|
- &msg_offset, 1);
|
|
|
- sep_dump(sctx->sep_used, "initial IV",
|
|
|
- bctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
- } else {
|
|
|
- /* Skip if ECB */
|
|
|
- msg_offset += max_length;
|
|
|
- }
|
|
|
- }
|
|
|
+ /* check for valid data and proper spacing */
|
|
|
+ src_ptr = sg_virt(ta_ctx->src_sg);
|
|
|
+ dst_ptr = sg_virt(ta_ctx->dst_sg);
|
|
|
|
|
|
- /* load the key */
|
|
|
- if (bctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
- sep_write_msg(sctx, (void *)&sctx->key.des.key1,
|
|
|
- sizeof(u32) * 8, sizeof(u32) * 8,
|
|
|
- &msg_offset, 1);
|
|
|
+ if (!src_ptr || !dst_ptr ||
|
|
|
+ (ta_ctx->current_cypher_req->nbytes %
|
|
|
+ crypto_ablkcipher_blocksize(tfm))) {
|
|
|
+
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "cipher block size odd\n");
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "cipher block size is %x\n",
|
|
|
+ crypto_ablkcipher_blocksize(tfm));
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "cipher data size is %x\n",
|
|
|
+ ta_ctx->current_cypher_req->nbytes);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- msg[0] = (u32)sctx->des_nbr_keys;
|
|
|
- msg[1] = (u32)bctx->des_encmode;
|
|
|
- msg[2] = (u32)bctx->des_opmode;
|
|
|
+ if (partial_overlap(src_ptr, dst_ptr,
|
|
|
+ ta_ctx->current_cypher_req->nbytes)) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "block partial overlap\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- sep_write_msg(sctx, (void *)msg,
|
|
|
- sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
- &msg_offset, 0);
|
|
|
- } else {
|
|
|
- sep_write_msg(sctx, (void *)&sctx->key.aes,
|
|
|
- sctx->keylen,
|
|
|
- SEP_AES_MAX_KEY_SIZE_BYTES,
|
|
|
- &msg_offset, 1);
|
|
|
+ /* Put together the message */
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, ta_ctx->block_opcode);
|
|
|
+
|
|
|
+ /* If des, and size is 1 block, put directly in msg */
|
|
|
+ if ((ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) &&
|
|
|
+ (req->nbytes == crypto_ablkcipher_blocksize(tfm))) {
|
|
|
+
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "writing out one block des\n");
|
|
|
+
|
|
|
+ copy_result = sg_copy_to_buffer(
|
|
|
+ ta_ctx->src_sg, sep_sg_nents(ta_ctx->src_sg),
|
|
|
+ small_buf, crypto_ablkcipher_blocksize(tfm));
|
|
|
|
|
|
- msg[0] = (u32)sctx->aes_key_size;
|
|
|
- msg[1] = (u32)bctx->aes_encmode;
|
|
|
- msg[2] = (u32)bctx->aes_opmode;
|
|
|
- msg[3] = (u32)0; /* Secret key is not used */
|
|
|
- sep_write_msg(sctx, (void *)msg,
|
|
|
- sizeof(u32) * 4, sizeof(u32) * 4,
|
|
|
- &msg_offset, 0);
|
|
|
+ if (copy_result != crypto_ablkcipher_blocksize(tfm)) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "des block copy faild\n");
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
+ /* Put data into message */
|
|
|
+ sep_write_msg(ta_ctx, small_buf,
|
|
|
+ crypto_ablkcipher_blocksize(tfm),
|
|
|
+ crypto_ablkcipher_blocksize(tfm) * 2,
|
|
|
+ &msg_offset, 1);
|
|
|
+
|
|
|
+ /* Put size into message */
|
|
|
+ sep_write_msg(ta_ctx, &req->nbytes,
|
|
|
+ sizeof(u32), sizeof(u32), &msg_offset, 0);
|
|
|
} else {
|
|
|
+ /* Otherwise, fill out dma tables */
|
|
|
+ ta_ctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
+ ta_ctx->dcb_input_data.data_in_size = req->nbytes;
|
|
|
+ ta_ctx->dcb_input_data.app_out_address = dst_ptr;
|
|
|
+ ta_ctx->dcb_input_data.block_size =
|
|
|
+ crypto_ablkcipher_blocksize(tfm);
|
|
|
+ ta_ctx->dcb_input_data.tail_block_size = 0;
|
|
|
+ ta_ctx->dcb_input_data.is_applet = 0;
|
|
|
+ ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
|
|
|
+ ta_ctx->dcb_input_data.dst_sg = ta_ctx->dst_sg;
|
|
|
+
|
|
|
+ result = sep_create_dcb_dmatables_context_kernel(
|
|
|
+ ta_ctx->sep_used,
|
|
|
+ &ta_ctx->dcb_region,
|
|
|
+ &ta_ctx->dmatables_region,
|
|
|
+ &ta_ctx->dma_ctx,
|
|
|
+ &ta_ctx->dcb_input_data,
|
|
|
+ 1);
|
|
|
+ if (result) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "crypto dma table create failed\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Portion of msg is nulled (no data) */
|
|
|
+ msg[0] = (u32)0;
|
|
|
+ msg[1] = (u32)0;
|
|
|
+ msg[2] = (u32)0;
|
|
|
+ msg[3] = (u32)0;
|
|
|
+ msg[4] = (u32)0;
|
|
|
+ sep_write_msg(ta_ctx, (void *)msg, sizeof(u32) * 5,
|
|
|
+ sizeof(u32) * 5, &msg_offset, 0);
|
|
|
+ }
|
|
|
|
|
|
- /* set nbytes for queue status */
|
|
|
- sctx->nbytes = req->nbytes;
|
|
|
+ /**
|
|
|
+ * Before we write the message, we need to overwrite the
|
|
|
+ * vendor's IV with the one from our own ablkcipher walk
|
|
|
+ * iv because this is needed for dm-crypt
|
|
|
+ */
|
|
|
+ sep_dump_ivs(req, "sending data block to sep\n");
|
|
|
+ if ((ta_ctx->current_request == DES_CBC) &&
|
|
|
+ (ta_ctx->des_opmode == SEP_DES_CBC)) {
|
|
|
+
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "overwrite vendor iv on DES\n");
|
|
|
+ des_internal = (struct sep_des_internal_context *)
|
|
|
+ sctx->des_private_ctx.ctx_buf;
|
|
|
+ memcpy((void *)des_internal->iv_context,
|
|
|
+ ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
|
|
|
+ } else if ((ta_ctx->current_request == AES_CBC) &&
|
|
|
+ (ta_ctx->aes_opmode == SEP_AES_CBC)) {
|
|
|
+
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "overwrite vendor iv on AES\n");
|
|
|
+ aes_internal = (struct sep_aes_internal_context *)
|
|
|
+ sctx->aes_private_ctx.cbuff;
|
|
|
+ memcpy((void *)aes_internal->aes_ctx_iv,
|
|
|
+ ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Write context into message */
|
|
|
+ if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
|
|
|
+ sep_write_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->des_private_ctx,
|
|
|
+ sizeof(struct sep_des_private_context));
|
|
|
+ sep_dump(ta_ctx->sep_used, "ctx to block des",
|
|
|
+ &sctx->des_private_ctx, 40);
|
|
|
+ } else {
|
|
|
+ sep_write_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->aes_private_ctx,
|
|
|
+ sizeof(struct sep_aes_private_context));
|
|
|
+ sep_dump(ta_ctx->sep_used, "ctx to block aes",
|
|
|
+ &sctx->aes_private_ctx, 20);
|
|
|
+ }
|
|
|
|
|
|
- /* Key already done; this is for data */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sending data\n");
|
|
|
+ /* conclude message */
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
|
|
|
- sep_dump_sg(sctx->sep_used,
|
|
|
- "block sg in", sctx->src_sg);
|
|
|
+ /* Parent (caller) is now ready to tell the sep to do ahead */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- /* check for valid data and proper spacing */
|
|
|
- src_ptr = sg_virt(sctx->src_sg);
|
|
|
- dst_ptr = sg_virt(sctx->dst_sg);
|
|
|
|
|
|
- if (!src_ptr || !dst_ptr ||
|
|
|
- (sctx->current_cypher_req->nbytes %
|
|
|
- crypto_ablkcipher_blocksize(tfm))) {
|
|
|
+/**
|
|
|
+ * This function sets things up for a crypto key submit process
|
|
|
+ * This does all preparation, but does not try to grab the
|
|
|
+ * sep
|
|
|
+ * @req: pointer to struct ablkcipher_request
|
|
|
+ * returns: 0 if all went well, non zero if error
|
|
|
+ */
|
|
|
+static int sep_crypto_send_key(struct ablkcipher_request *req)
|
|
|
+{
|
|
|
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "cipher block size odd\n");
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "cipher block size is %x\n",
|
|
|
- crypto_ablkcipher_blocksize(tfm));
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "cipher data size is %x\n",
|
|
|
- sctx->current_cypher_req->nbytes);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return;
|
|
|
- }
|
|
|
+ int int_error;
|
|
|
+ u32 msg_offset;
|
|
|
+ static u32 msg[10];
|
|
|
|
|
|
- if (partial_overlap(src_ptr, dst_ptr,
|
|
|
- sctx->current_cypher_req->nbytes)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "block partial overlap\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return;
|
|
|
- }
|
|
|
+ u32 max_length;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
+ struct crypto_ablkcipher *tfm;
|
|
|
+ struct sep_system_ctx *sctx;
|
|
|
|
|
|
- /* Put together the message */
|
|
|
- sep_make_header(sctx, &msg_offset, bctx->block_opcode);
|
|
|
+ ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+ tfm = crypto_ablkcipher_reqtfm(req);
|
|
|
+ sctx = crypto_ablkcipher_ctx(tfm);
|
|
|
|
|
|
- /* If des, and size is 1 block, put directly in msg */
|
|
|
- if ((bctx->block_opcode == SEP_DES_BLOCK_OPCODE) &&
|
|
|
- (req->nbytes == crypto_ablkcipher_blocksize(tfm))) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending key\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "writing out one block des\n");
|
|
|
+ /* start the walk on scatterlists */
|
|
|
+ ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "sep crypto block data size of %x\n", req->nbytes);
|
|
|
|
|
|
- copy_result = sg_copy_to_buffer(
|
|
|
- sctx->src_sg, sep_sg_nents(sctx->src_sg),
|
|
|
- small_buf, crypto_ablkcipher_blocksize(tfm));
|
|
|
+ int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
|
|
|
+ if (int_error) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
|
|
|
+ int_error);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
|
|
|
- if (copy_result != crypto_ablkcipher_blocksize(tfm)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "des block copy faild\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
- return;
|
|
|
- }
|
|
|
+ /* check iv */
|
|
|
+ if ((ta_ctx->current_request == DES_CBC) &&
|
|
|
+ (ta_ctx->des_opmode == SEP_DES_CBC)) {
|
|
|
+ if (!ta_ctx->walk.iv) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- /* Put data into message */
|
|
|
- sep_write_msg(sctx, small_buf,
|
|
|
- crypto_ablkcipher_blocksize(tfm),
|
|
|
- crypto_ablkcipher_blocksize(tfm) * 2,
|
|
|
- &msg_offset, 1);
|
|
|
+ memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
+ sep_dump(ta_ctx->sep_used, "iv",
|
|
|
+ ta_ctx->iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
+ }
|
|
|
|
|
|
- /* Put size into message */
|
|
|
- sep_write_msg(sctx, &req->nbytes,
|
|
|
- sizeof(u32), sizeof(u32), &msg_offset, 0);
|
|
|
+ if ((ta_ctx->current_request == AES_CBC) &&
|
|
|
+ (ta_ctx->aes_opmode == SEP_AES_CBC)) {
|
|
|
+ if (!ta_ctx->walk.iv) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
+ sep_dump(ta_ctx->sep_used, "iv",
|
|
|
+ ta_ctx->iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* put together message to SEP */
|
|
|
+ /* Start with op code */
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, ta_ctx->init_opcode);
|
|
|
+
|
|
|
+ /* now deal with IV */
|
|
|
+ if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
+ if (ta_ctx->des_opmode == SEP_DES_CBC) {
|
|
|
+ sep_write_msg(ta_ctx, ta_ctx->iv,
|
|
|
+ SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4,
|
|
|
+ &msg_offset, 1);
|
|
|
+ sep_dump(ta_ctx->sep_used, "initial IV",
|
|
|
+ ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
|
|
|
+ } else {
|
|
|
+ /* Skip if ECB */
|
|
|
+ msg_offset += 4 * sizeof(u32);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ max_length = ((SEP_AES_IV_SIZE_BYTES + 3) /
|
|
|
+ sizeof(u32)) * sizeof(u32);
|
|
|
+ if (ta_ctx->aes_opmode == SEP_AES_CBC) {
|
|
|
+ sep_write_msg(ta_ctx, ta_ctx->iv,
|
|
|
+ SEP_AES_IV_SIZE_BYTES, max_length,
|
|
|
+ &msg_offset, 1);
|
|
|
+ sep_dump(ta_ctx->sep_used, "initial IV",
|
|
|
+ ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
|
|
|
} else {
|
|
|
- /* Otherwise, fill out dma tables */
|
|
|
- sctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
- sctx->dcb_input_data.data_in_size = req->nbytes;
|
|
|
- sctx->dcb_input_data.app_out_address = dst_ptr;
|
|
|
- sctx->dcb_input_data.block_size =
|
|
|
- crypto_ablkcipher_blocksize(tfm);
|
|
|
- sctx->dcb_input_data.tail_block_size = 0;
|
|
|
- sctx->dcb_input_data.is_applet = 0;
|
|
|
- sctx->dcb_input_data.src_sg = sctx->src_sg;
|
|
|
- sctx->dcb_input_data.dst_sg = sctx->dst_sg;
|
|
|
-
|
|
|
- result = sep_create_dcb_dmatables_context_kernel(
|
|
|
- sctx->sep_used,
|
|
|
- &sctx->dcb_region,
|
|
|
- &sctx->dmatables_region,
|
|
|
- &sctx->dma_ctx,
|
|
|
- &sctx->dcb_input_data,
|
|
|
- 1);
|
|
|
- if (result) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "crypto dma table create failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return;
|
|
|
+ /* Skip if ECB */
|
|
|
+ msg_offset += max_length;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ /* load the key */
|
|
|
+ if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
+ sep_write_msg(ta_ctx, (void *)&sctx->key.des.key1,
|
|
|
+ sizeof(u32) * 8, sizeof(u32) * 8,
|
|
|
+ &msg_offset, 1);
|
|
|
+
|
|
|
+ msg[0] = (u32)sctx->des_nbr_keys;
|
|
|
+ msg[1] = (u32)ta_ctx->des_encmode;
|
|
|
+ msg[2] = (u32)ta_ctx->des_opmode;
|
|
|
|
|
|
- /* Portion of msg is nulled (no data) */
|
|
|
- msg[0] = (u32)0;
|
|
|
- msg[1] = (u32)0;
|
|
|
- msg[2] = (u32)0;
|
|
|
- msg[3] = (u32)0;
|
|
|
- msg[4] = (u32)0;
|
|
|
- sep_write_msg(sctx, (void *)msg,
|
|
|
- sizeof(u32) * 5,
|
|
|
- sizeof(u32) * 5,
|
|
|
- &msg_offset, 0);
|
|
|
+ sep_write_msg(ta_ctx, (void *)msg,
|
|
|
+ sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
+ &msg_offset, 0);
|
|
|
+ } else {
|
|
|
+ sep_write_msg(ta_ctx, (void *)&sctx->key.aes,
|
|
|
+ sctx->keylen,
|
|
|
+ SEP_AES_MAX_KEY_SIZE_BYTES,
|
|
|
+ &msg_offset, 1);
|
|
|
+
|
|
|
+ msg[0] = (u32)sctx->aes_key_size;
|
|
|
+ msg[1] = (u32)ta_ctx->aes_encmode;
|
|
|
+ msg[2] = (u32)ta_ctx->aes_opmode;
|
|
|
+ msg[3] = (u32)0; /* Secret key is not used */
|
|
|
+ sep_write_msg(ta_ctx, (void *)msg,
|
|
|
+ sizeof(u32) * 4, sizeof(u32) * 4,
|
|
|
+ &msg_offset, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* conclude message */
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
+
|
|
|
+ /* Parent (caller) is now ready to tell the sep to do ahead */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/* This needs to be run as a work queue as it can be put asleep */
|
|
|
+static void sep_crypto_block(void *data)
|
|
|
+{
|
|
|
+ unsigned long end_time;
|
|
|
+
|
|
|
+ int result;
|
|
|
+
|
|
|
+ struct ablkcipher_request *req;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
+ struct crypto_ablkcipher *tfm;
|
|
|
+ struct sep_system_ctx *sctx;
|
|
|
+ int are_we_done_yet;
|
|
|
+
|
|
|
+ req = (struct ablkcipher_request *)data;
|
|
|
+ ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+ tfm = crypto_ablkcipher_reqtfm(req);
|
|
|
+ sctx = crypto_ablkcipher_ctx(tfm);
|
|
|
+
|
|
|
+ ta_ctx->are_we_done_yet = &are_we_done_yet;
|
|
|
+
|
|
|
+ pr_debug("sep_crypto_block\n");
|
|
|
+ pr_debug("tfm is %p sctx is %p ta_ctx is %p\n",
|
|
|
+ tfm, sctx, ta_ctx);
|
|
|
+ pr_debug("key_sent is %d\n", sctx->key_sent);
|
|
|
+
|
|
|
+ /* do we need to send the key */
|
|
|
+ if (sctx->key_sent == 0) {
|
|
|
+ are_we_done_yet = 0;
|
|
|
+ result = sep_crypto_send_key(req); /* prep to send key */
|
|
|
+ if (result != 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "could not prep key %x\n", result);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, result);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- /* Write context into message */
|
|
|
- if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
|
|
|
- sep_write_context(sctx, &msg_offset,
|
|
|
- &bctx->des_private_ctx,
|
|
|
- sizeof(struct sep_des_private_context));
|
|
|
- sep_dump(sctx->sep_used, "ctx to block des",
|
|
|
- &bctx->des_private_ctx, 40);
|
|
|
- } else {
|
|
|
- sep_write_context(sctx, &msg_offset,
|
|
|
- &bctx->aes_private_ctx,
|
|
|
- sizeof(struct sep_aes_private_context));
|
|
|
- sep_dump(sctx->sep_used, "ctx to block aes",
|
|
|
- &bctx->aes_private_ctx, 20);
|
|
|
+ result = sep_crypto_take_sep(ta_ctx);
|
|
|
+ if (result) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "sep_crypto_take_sep for key send failed\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, result);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) &&
|
|
|
+ (are_we_done_yet == 0))
|
|
|
+ schedule();
|
|
|
+
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "Send key job never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ /* Set the key sent variable so this can be skipped later */
|
|
|
+ sctx->key_sent = 1;
|
|
|
}
|
|
|
|
|
|
- /* conclude message and then tell sep to do its thing */
|
|
|
- sctx->done_with_transaction = 0;
|
|
|
+ /* Key sent (or maybe not if we did not have to), now send block */
|
|
|
+ are_we_done_yet = 0;
|
|
|
|
|
|
- sep_end_msg(sctx, msg_offset);
|
|
|
- result = sep_crypto_take_sep(sctx);
|
|
|
- if (result) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_crypto_take_sep failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ result = sep_crypto_block_data(req);
|
|
|
+
|
|
|
+ if (result != 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "could prep not send block %x\n", result);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, result);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sep is now working. Lets wait up to 5 seconds
|
|
|
- * for completion. If it does not complete, we will do
|
|
|
- * a crypto release with -EINVAL to release the
|
|
|
- * kernel crypto infrastructure and let the system
|
|
|
- * continue to boot up
|
|
|
- * We have to wait this long because some crypto
|
|
|
- * operations can take a while
|
|
|
- */
|
|
|
-
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "waiting for done with transaction\n");
|
|
|
+ result = sep_crypto_take_sep(ta_ctx);
|
|
|
+ if (result) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "sep_crypto_take_sep for block send failed\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, result);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ);
|
|
|
- while ((time_before(jiffies, sctx->end_time)) &&
|
|
|
- (!sctx->done_with_transaction))
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
|
|
|
schedule();
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "done waiting for done with transaction\n");
|
|
|
-
|
|
|
- /* are we done? */
|
|
|
- if (!sctx->done_with_transaction) {
|
|
|
- /* Nope, lets release and tell crypto no */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "[PID%d] sep_crypto_block never finished\n",
|
|
|
- current->pid);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "Send block job never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ /* That's it; entire thing done, get out of queue */
|
|
|
+
|
|
|
+ pr_debug("crypto_block leaving\n");
|
|
|
+ pr_debug("tfm is %p sctx is %p ta_ctx is %p\n", tfm, sctx, ta_ctx);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1405,7 +1614,6 @@ static void sep_crypto_block(void *data)
|
|
|
static u32 crypto_post_op(struct sep_device *sep)
|
|
|
{
|
|
|
/* HERE */
|
|
|
- int int_error;
|
|
|
u32 u32_error;
|
|
|
u32 msg_offset;
|
|
|
|
|
@@ -1413,169 +1621,185 @@ static u32 crypto_post_op(struct sep_device *sep)
|
|
|
static char small_buf[100];
|
|
|
|
|
|
struct ablkcipher_request *req;
|
|
|
- struct sep_block_ctx *bctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
struct crypto_ablkcipher *tfm;
|
|
|
|
|
|
+ struct sep_des_internal_context *des_internal;
|
|
|
+ struct sep_aes_internal_context *aes_internal;
|
|
|
+
|
|
|
if (!sep->current_cypher_req)
|
|
|
return -EINVAL;
|
|
|
|
|
|
/* hold req since we need to submit work after clearing sep */
|
|
|
req = sep->current_cypher_req;
|
|
|
|
|
|
- bctx = ablkcipher_request_ctx(sep->current_cypher_req);
|
|
|
+ ta_ctx = ablkcipher_request_ctx(sep->current_cypher_req);
|
|
|
tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req);
|
|
|
sctx = crypto_ablkcipher_ctx(tfm);
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op\n");
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op message dump\n");
|
|
|
- crypto_sep_dump_message(sctx);
|
|
|
+ pr_debug("crypto_post op\n");
|
|
|
+ pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
|
|
|
+ sctx->key_sent, tfm, sctx, ta_ctx);
|
|
|
|
|
|
- sctx->done_with_transaction = 1;
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op\n");
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op message dump\n");
|
|
|
+ crypto_sep_dump_message(ta_ctx->sep_used, ta_ctx->msg);
|
|
|
|
|
|
/* first bring msg from shared area to local area */
|
|
|
- memcpy(sctx->msg, sep->shared_addr,
|
|
|
+ memcpy(ta_ctx->msg, sep->shared_addr,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
/* Is this the result of performing init (key to SEP */
|
|
|
if (sctx->key_sent == 0) {
|
|
|
|
|
|
/* Did SEP do it okay */
|
|
|
- u32_error = sep_verify_op(sctx, bctx->init_opcode,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, ta_ctx->init_opcode,
|
|
|
&msg_offset);
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"aes init error %x\n", u32_error);
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return u32_error;
|
|
|
}
|
|
|
|
|
|
/* Read Context */
|
|
|
- if (bctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &bctx->des_private_ctx,
|
|
|
+ if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->des_private_ctx,
|
|
|
sizeof(struct sep_des_private_context));
|
|
|
|
|
|
- sep_dump(sctx->sep_used, "ctx init des",
|
|
|
- &bctx->des_private_ctx, 40);
|
|
|
+ sep_dump(ta_ctx->sep_used, "ctx init des",
|
|
|
+ &sctx->des_private_ctx, 40);
|
|
|
} else {
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &bctx->aes_private_ctx,
|
|
|
- sizeof(struct sep_des_private_context));
|
|
|
-
|
|
|
- sep_dump(sctx->sep_used, "ctx init aes",
|
|
|
- &bctx->aes_private_ctx, 20);
|
|
|
- }
|
|
|
-
|
|
|
- /* We are done with init. Now send out the data */
|
|
|
- /* first release the sep */
|
|
|
- sctx->key_sent = 1;
|
|
|
- sep_crypto_release(sctx, -EINPROGRESS);
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->aes_private_ctx,
|
|
|
+ sizeof(struct sep_aes_private_context));
|
|
|
|
|
|
- spin_lock_irq(&queue_lock);
|
|
|
- int_error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((int_error != 0) && (int_error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "spe cypher post op cant queue\n");
|
|
|
- sep_crypto_release(sctx, int_error);
|
|
|
- return int_error;
|
|
|
+ sep_dump(ta_ctx->sep_used, "ctx init aes",
|
|
|
+ &sctx->aes_private_ctx, 20);
|
|
|
}
|
|
|
|
|
|
- /* schedule the data send */
|
|
|
- int_error = sep_submit_work(sep->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
+ sep_dump_ivs(req, "after sending key to sep\n");
|
|
|
|
|
|
- if (int_error) {
|
|
|
- dev_warn(&sep->pdev->dev,
|
|
|
- "cant submit work sep_crypto_block\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ /* key sent went okay; release sep, and set are_we_done_yet */
|
|
|
+ sctx->key_sent = 1;
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINPROGRESS);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
/**
|
|
|
* This is the result of a block request
|
|
|
*/
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"crypto_post_op block response\n");
|
|
|
|
|
|
- u32_error = sep_verify_op(sctx, bctx->block_opcode,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, ta_ctx->block_opcode,
|
|
|
&msg_offset);
|
|
|
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep block error %x\n", u32_error);
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
|
|
|
+ if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"post op for DES\n");
|
|
|
|
|
|
/* special case for 1 block des */
|
|
|
if (sep->current_cypher_req->nbytes ==
|
|
|
crypto_ablkcipher_blocksize(tfm)) {
|
|
|
|
|
|
- sep_read_msg(sctx, small_buf,
|
|
|
+ sep_read_msg(ta_ctx, small_buf,
|
|
|
crypto_ablkcipher_blocksize(tfm),
|
|
|
crypto_ablkcipher_blocksize(tfm) * 2,
|
|
|
&msg_offset, 1);
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"reading in block des\n");
|
|
|
|
|
|
copy_result = sg_copy_from_buffer(
|
|
|
- sctx->dst_sg,
|
|
|
- sep_sg_nents(sctx->dst_sg),
|
|
|
+ ta_ctx->dst_sg,
|
|
|
+ sep_sg_nents(ta_ctx->dst_sg),
|
|
|
small_buf,
|
|
|
crypto_ablkcipher_blocksize(tfm));
|
|
|
|
|
|
if (copy_result !=
|
|
|
crypto_ablkcipher_blocksize(tfm)) {
|
|
|
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"des block copy faild\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx,
|
|
|
+ -ENOMEM);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Read Context */
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &bctx->des_private_ctx,
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->des_private_ctx,
|
|
|
sizeof(struct sep_des_private_context));
|
|
|
} else {
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"post op for AES\n");
|
|
|
|
|
|
/* Skip the MAC Output */
|
|
|
msg_offset += (sizeof(u32) * 4);
|
|
|
|
|
|
/* Read Context */
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &bctx->aes_private_ctx,
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->aes_private_ctx,
|
|
|
sizeof(struct sep_aes_private_context));
|
|
|
}
|
|
|
|
|
|
- sep_dump_sg(sctx->sep_used,
|
|
|
- "block sg out", sctx->dst_sg);
|
|
|
+ sep_dump_sg(ta_ctx->sep_used,
|
|
|
+ "block sg out", ta_ctx->dst_sg);
|
|
|
|
|
|
/* Copy to correct sg if this block had oddball pages */
|
|
|
- if (sctx->dst_sg_hold)
|
|
|
- sep_copy_sg(sctx->sep_used,
|
|
|
- sctx->dst_sg,
|
|
|
- sctx->current_cypher_req->dst,
|
|
|
- sctx->current_cypher_req->nbytes);
|
|
|
+ if (ta_ctx->dst_sg_hold)
|
|
|
+ sep_copy_sg(ta_ctx->sep_used,
|
|
|
+ ta_ctx->dst_sg,
|
|
|
+ ta_ctx->current_cypher_req->dst,
|
|
|
+ ta_ctx->current_cypher_req->nbytes);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Copy the iv's back to the walk.iv
|
|
|
+ * This is required for dm_crypt
|
|
|
+ */
|
|
|
+ sep_dump_ivs(req, "got data block from sep\n");
|
|
|
+ if ((ta_ctx->current_request == DES_CBC) &&
|
|
|
+ (ta_ctx->des_opmode == SEP_DES_CBC)) {
|
|
|
+
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "returning result iv to walk on DES\n");
|
|
|
+ des_internal = (struct sep_des_internal_context *)
|
|
|
+ sctx->des_private_ctx.ctx_buf;
|
|
|
+ memcpy(ta_ctx->walk.iv,
|
|
|
+ (void *)des_internal->iv_context,
|
|
|
+ crypto_ablkcipher_ivsize(tfm));
|
|
|
+ } else if ((ta_ctx->current_request == AES_CBC) &&
|
|
|
+ (ta_ctx->aes_opmode == SEP_AES_CBC)) {
|
|
|
+
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "returning result iv to walk on AES\n");
|
|
|
+ aes_internal = (struct sep_aes_internal_context *)
|
|
|
+ sctx->aes_private_ctx.cbuff;
|
|
|
+ memcpy(ta_ctx->walk.iv,
|
|
|
+ (void *)aes_internal->aes_ctx_iv,
|
|
|
+ crypto_ablkcipher_ivsize(tfm));
|
|
|
+ }
|
|
|
|
|
|
/* finished, release everything */
|
|
|
- sep_crypto_release(sctx, 0);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, 0);
|
|
|
}
|
|
|
+ pr_debug("crypto_post_op done\n");
|
|
|
+ pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
|
|
|
+ sctx->key_sent, tfm, sctx, ta_ctx);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1584,35 +1808,33 @@ static u32 hash_init_post_op(struct sep_device *sep)
|
|
|
u32 u32_error;
|
|
|
u32 msg_offset;
|
|
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash init post op\n");
|
|
|
|
|
|
- sctx->done_with_transaction = 1;
|
|
|
-
|
|
|
/* first bring msg from shared area to local area */
|
|
|
- memcpy(sctx->msg, sep->shared_addr,
|
|
|
+ memcpy(ta_ctx->msg, sep->shared_addr,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
- u32_error = sep_verify_op(sctx, SEP_HASH_INIT_OPCODE,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, SEP_HASH_INIT_OPCODE,
|
|
|
&msg_offset);
|
|
|
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n",
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
|
|
|
u32_error);
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return u32_error;
|
|
|
}
|
|
|
|
|
|
/* Read Context */
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &ctx->hash_private_ctx,
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->hash_private_ctx,
|
|
|
sizeof(struct sep_hash_private_context));
|
|
|
|
|
|
/* Signal to crypto infrastructure and clear out */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "hash init post op done\n");
|
|
|
- sep_crypto_release(sctx, 0);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash init post op done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, 0);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1621,33 +1843,69 @@ static u32 hash_update_post_op(struct sep_device *sep)
|
|
|
u32 u32_error;
|
|
|
u32 msg_offset;
|
|
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash update post op\n");
|
|
|
|
|
|
- sctx->done_with_transaction = 1;
|
|
|
-
|
|
|
/* first bring msg from shared area to local area */
|
|
|
- memcpy(sctx->msg, sep->shared_addr,
|
|
|
+ memcpy(ta_ctx->msg, sep->shared_addr,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
- u32_error = sep_verify_op(sctx, SEP_HASH_UPDATE_OPCODE,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, SEP_HASH_UPDATE_OPCODE,
|
|
|
&msg_offset);
|
|
|
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n",
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
|
|
|
u32_error);
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return u32_error;
|
|
|
}
|
|
|
|
|
|
/* Read Context */
|
|
|
- sep_read_context(sctx, &msg_offset,
|
|
|
- &ctx->hash_private_ctx,
|
|
|
+ sep_read_context(ta_ctx, &msg_offset,
|
|
|
+ &sctx->hash_private_ctx,
|
|
|
sizeof(struct sep_hash_private_context));
|
|
|
|
|
|
- sep_crypto_release(sctx, 0);
|
|
|
+ /**
|
|
|
+ * Following is only for finup; if we just completd the
|
|
|
+ * data portion of finup, we now need to kick off the
|
|
|
+ * finish portion of finup.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (ta_ctx->sep_used->current_hash_stage == HASH_FINUP_DATA) {
|
|
|
+
|
|
|
+ /* first reset stage to HASH_FINUP_FINISH */
|
|
|
+ ta_ctx->sep_used->current_hash_stage = HASH_FINUP_FINISH;
|
|
|
+
|
|
|
+ /* now enqueue the finish operation */
|
|
|
+ spin_lock_irq(&queue_lock);
|
|
|
+ u32_error = crypto_enqueue_request(&sep_queue,
|
|
|
+ &ta_ctx->sep_used->current_hash_req->base);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+
|
|
|
+ if ((u32_error != 0) && (u32_error != -EINPROGRESS)) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "spe cypher post op cant queue\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
+ return u32_error;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* schedule the data send */
|
|
|
+ u32_error = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+
|
|
|
+ if (u32_error) {
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "cant submit work sep_crypto_block\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Signal to crypto infrastructure and clear out */
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash update post op done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, 0);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1658,45 +1916,44 @@ static u32 hash_final_post_op(struct sep_device *sep)
|
|
|
u32 msg_offset;
|
|
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
|
|
|
struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash final post op\n");
|
|
|
|
|
|
- sctx->done_with_transaction = 1;
|
|
|
-
|
|
|
/* first bring msg from shared area to local area */
|
|
|
- memcpy(sctx->msg, sep->shared_addr,
|
|
|
+ memcpy(ta_ctx->msg, sep->shared_addr,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
- u32_error = sep_verify_op(sctx, SEP_HASH_FINISH_OPCODE,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, SEP_HASH_FINISH_OPCODE,
|
|
|
&msg_offset);
|
|
|
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "hash finish error %x\n",
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev, "hash finish error %x\n",
|
|
|
u32_error);
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return u32_error;
|
|
|
}
|
|
|
|
|
|
/* Grab the result */
|
|
|
- if (sctx->current_hash_req->result == NULL) {
|
|
|
+ if (ta_ctx->current_hash_req->result == NULL) {
|
|
|
/* Oops, null buffer; error out here */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash finish null buffer\n");
|
|
|
- sep_crypto_release(sctx, (u32)-ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
|
|
|
sizeof(u32)) * sizeof(u32);
|
|
|
|
|
|
- sep_read_msg(sctx,
|
|
|
- sctx->current_hash_req->result,
|
|
|
+ sep_read_msg(ta_ctx,
|
|
|
+ ta_ctx->current_hash_req->result,
|
|
|
crypto_ahash_digestsize(tfm), max_length,
|
|
|
&msg_offset, 0);
|
|
|
|
|
|
/* Signal to crypto infrastructure and clear out */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "hash finish post op done\n");
|
|
|
- sep_crypto_release(sctx, 0);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash finish post op done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, 0);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1707,48 +1964,47 @@ static u32 hash_digest_post_op(struct sep_device *sep)
|
|
|
u32 msg_offset;
|
|
|
struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
|
|
|
struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash digest post op\n");
|
|
|
|
|
|
- sctx->done_with_transaction = 1;
|
|
|
-
|
|
|
/* first bring msg from shared area to local area */
|
|
|
- memcpy(sctx->msg, sep->shared_addr,
|
|
|
+ memcpy(ta_ctx->msg, sep->shared_addr,
|
|
|
SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
|
|
|
|
|
|
- u32_error = sep_verify_op(sctx, SEP_HASH_SINGLE_OPCODE,
|
|
|
+ u32_error = sep_verify_op(ta_ctx, SEP_HASH_SINGLE_OPCODE,
|
|
|
&msg_offset);
|
|
|
|
|
|
if (u32_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash digest finish error %x\n", u32_error);
|
|
|
|
|
|
- sep_crypto_release(sctx, u32_error);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, u32_error);
|
|
|
return u32_error;
|
|
|
}
|
|
|
|
|
|
/* Grab the result */
|
|
|
- if (sctx->current_hash_req->result == NULL) {
|
|
|
+ if (ta_ctx->current_hash_req->result == NULL) {
|
|
|
/* Oops, null buffer; error out here */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash digest finish null buffer\n");
|
|
|
- sep_crypto_release(sctx, (u32)-ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
|
|
|
sizeof(u32)) * sizeof(u32);
|
|
|
|
|
|
- sep_read_msg(sctx,
|
|
|
- sctx->current_hash_req->result,
|
|
|
+ sep_read_msg(ta_ctx,
|
|
|
+ ta_ctx->current_hash_req->result,
|
|
|
crypto_ahash_digestsize(tfm), max_length,
|
|
|
&msg_offset, 0);
|
|
|
|
|
|
/* Signal to crypto infrastructure and clear out */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash digest finish post op done\n");
|
|
|
|
|
|
- sep_crypto_release(sctx, 0);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, 0);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1759,7 +2015,6 @@ static u32 hash_digest_post_op(struct sep_device *sep)
|
|
|
*/
|
|
|
static void sep_finish(unsigned long data)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
struct sep_device *sep_dev;
|
|
|
int res;
|
|
|
|
|
@@ -1776,18 +2031,15 @@ static void sep_finish(unsigned long data)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&sep_dev->busy_lock, flags);
|
|
|
if (sep_dev->in_kernel == (u32)0) {
|
|
|
- spin_unlock_irqrestore(&sep_dev->busy_lock, flags);
|
|
|
dev_warn(&sep_dev->pdev->dev,
|
|
|
"sep_finish; not in kernel operation\n");
|
|
|
return;
|
|
|
}
|
|
|
- spin_unlock_irqrestore(&sep_dev->busy_lock, flags);
|
|
|
|
|
|
/* Did we really do a sep command prior to this? */
|
|
|
if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
|
|
|
- &sep_dev->sctx->call_status.status)) {
|
|
|
+ &sep_dev->ta_ctx->call_status.status)) {
|
|
|
|
|
|
dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n",
|
|
|
current->pid);
|
|
@@ -1856,8 +2108,10 @@ static void sep_finish(unsigned long data)
|
|
|
res = hash_init_post_op(sep_dev);
|
|
|
break;
|
|
|
case HASH_UPDATE:
|
|
|
+ case HASH_FINUP_DATA:
|
|
|
res = hash_update_post_op(sep_dev);
|
|
|
break;
|
|
|
+ case HASH_FINUP_FINISH:
|
|
|
case HASH_FINISH:
|
|
|
res = hash_final_post_op(sep_dev);
|
|
|
break;
|
|
@@ -1865,43 +2119,31 @@ static void sep_finish(unsigned long data)
|
|
|
res = hash_digest_post_op(sep_dev);
|
|
|
break;
|
|
|
default:
|
|
|
- dev_warn(&sep_dev->pdev->dev,
|
|
|
- "invalid stage for hash finish\n");
|
|
|
+ pr_debug("sep - invalid stage for hash finish\n");
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
- dev_warn(&sep_dev->pdev->dev,
|
|
|
- "invalid request for finish\n");
|
|
|
+ pr_debug("sep - invalid request for finish\n");
|
|
|
}
|
|
|
|
|
|
- if (res) {
|
|
|
- dev_warn(&sep_dev->pdev->dev,
|
|
|
- "finish returned error %x\n", res);
|
|
|
- }
|
|
|
+ if (res)
|
|
|
+ pr_debug("sep - finish returned error %x\n", res);
|
|
|
}
|
|
|
|
|
|
static int sep_hash_cra_init(struct crypto_tfm *tfm)
|
|
|
{
|
|
|
- struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm);
|
|
|
const char *alg_name = crypto_tfm_alg_name(tfm);
|
|
|
|
|
|
- sctx->sep_used = sep_dev;
|
|
|
-
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_hash_cra_init name is %s\n", alg_name);
|
|
|
+ pr_debug("sep_hash_cra_init name is %s\n", alg_name);
|
|
|
|
|
|
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
|
|
|
- sizeof(struct sep_hash_ctx));
|
|
|
+ sizeof(struct this_task_ctx));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static void sep_hash_cra_exit(struct crypto_tfm *tfm)
|
|
|
{
|
|
|
- struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm);
|
|
|
-
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_hash_cra_exit\n");
|
|
|
- sctx->sep_used = NULL;
|
|
|
+ pr_debug("sep_hash_cra_exit\n");
|
|
|
}
|
|
|
|
|
|
static void sep_hash_init(void *data)
|
|
@@ -1910,60 +2152,49 @@ static void sep_hash_init(void *data)
|
|
|
int result;
|
|
|
struct ahash_request *req;
|
|
|
struct crypto_ahash *tfm;
|
|
|
- struct sep_hash_ctx *ctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
+ unsigned long end_time;
|
|
|
+ int are_we_done_yet;
|
|
|
|
|
|
req = (struct ahash_request *)data;
|
|
|
tfm = crypto_ahash_reqtfm(req);
|
|
|
- ctx = ahash_request_ctx(req);
|
|
|
sctx = crypto_ahash_ctx(tfm);
|
|
|
+ ta_ctx = ahash_request_ctx(req);
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+
|
|
|
+ ta_ctx->are_we_done_yet = &are_we_done_yet;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_init\n");
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ ta_ctx->current_hash_stage = HASH_INIT;
|
|
|
/* opcode and mode */
|
|
|
- sep_make_header(sctx, &msg_offset, SEP_HASH_INIT_OPCODE);
|
|
|
- sep_write_msg(sctx, &ctx->hash_opmode,
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, SEP_HASH_INIT_OPCODE);
|
|
|
+ sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
|
|
|
sizeof(u32), sizeof(u32), &msg_offset, 0);
|
|
|
- sep_end_msg(sctx, msg_offset);
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
|
|
|
- sctx->done_with_transaction = 0;
|
|
|
-
|
|
|
- result = sep_crypto_take_sep(sctx);
|
|
|
+ are_we_done_yet = 0;
|
|
|
+ result = sep_crypto_take_sep(ta_ctx);
|
|
|
if (result) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_init take sep failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sep is now working. Lets wait up to 5 seconds
|
|
|
- * for completion. If it does not complete, we will do
|
|
|
- * a crypto release with -EINVAL to release the
|
|
|
- * kernel crypto infrastructure and let the system
|
|
|
- * continue to boot up
|
|
|
- * We have to wait this long because some crypto
|
|
|
- * operations can take a while
|
|
|
- */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "waiting for done with transaction\n");
|
|
|
-
|
|
|
- sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ);
|
|
|
- while ((time_before(jiffies, sctx->end_time)) &&
|
|
|
- (!sctx->done_with_transaction))
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
|
|
|
schedule();
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "done waiting for done with transaction\n");
|
|
|
-
|
|
|
- /* are we done? */
|
|
|
- if (!sctx->done_with_transaction) {
|
|
|
- /* Nope, lets release and tell crypto no */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "[PID%d] sep_hash_init never finished\n",
|
|
|
- current->pid);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "hash init never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static void sep_hash_update(void *data)
|
|
@@ -1975,6 +2206,8 @@ static void sep_hash_update(void *data)
|
|
|
u32 block_size;
|
|
|
u32 head_len;
|
|
|
u32 tail_len;
|
|
|
+ int are_we_done_yet;
|
|
|
+
|
|
|
static u32 msg[10];
|
|
|
static char small_buf[100];
|
|
|
void *src_ptr;
|
|
@@ -1982,184 +2215,174 @@ static void sep_hash_update(void *data)
|
|
|
ssize_t copy_result;
|
|
|
struct ahash_request *req;
|
|
|
struct crypto_ahash *tfm;
|
|
|
- struct sep_hash_ctx *ctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
+ unsigned long end_time;
|
|
|
|
|
|
req = (struct ahash_request *)data;
|
|
|
tfm = crypto_ahash_reqtfm(req);
|
|
|
- ctx = ahash_request_ctx(req);
|
|
|
sctx = crypto_ahash_ctx(tfm);
|
|
|
+ ta_ctx = ahash_request_ctx(req);
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+
|
|
|
+ ta_ctx->are_we_done_yet = &are_we_done_yet;
|
|
|
|
|
|
/* length for queue status */
|
|
|
- sctx->nbytes = req->nbytes;
|
|
|
+ ta_ctx->nbytes = req->nbytes;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_update\n");
|
|
|
- sctx->current_hash_stage = HASH_UPDATE;
|
|
|
+ ta_ctx->current_hash_stage = HASH_UPDATE;
|
|
|
len = req->nbytes;
|
|
|
|
|
|
block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
|
|
|
tail_len = req->nbytes % block_size;
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", len);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", len);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
|
|
|
|
|
|
/* Compute header/tail sizes */
|
|
|
- int_ctx = (struct sep_hash_internal_context *)&ctx->
|
|
|
+ int_ctx = (struct sep_hash_internal_context *)&sctx->
|
|
|
hash_private_ctx.internal_context;
|
|
|
head_len = (block_size - int_ctx->prev_update_bytes) % block_size;
|
|
|
tail_len = (req->nbytes - head_len) % block_size;
|
|
|
|
|
|
/* Make sure all pages are even block */
|
|
|
- int_error = sep_oddball_pages(sctx->sep_used, req->src,
|
|
|
+ int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
|
|
|
req->nbytes,
|
|
|
block_size, &new_sg, 1);
|
|
|
|
|
|
if (int_error < 0) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"oddball pages error in crash update\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -ENOMEM);
|
|
|
return;
|
|
|
} else if (int_error == 1) {
|
|
|
- sctx->src_sg = new_sg;
|
|
|
- sctx->src_sg_hold = new_sg;
|
|
|
+ ta_ctx->src_sg = new_sg;
|
|
|
+ ta_ctx->src_sg_hold = new_sg;
|
|
|
} else {
|
|
|
- sctx->src_sg = req->src;
|
|
|
- sctx->src_sg_hold = NULL;
|
|
|
+ ta_ctx->src_sg = req->src;
|
|
|
+ ta_ctx->src_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- src_ptr = sg_virt(sctx->src_sg);
|
|
|
+ src_ptr = sg_virt(ta_ctx->src_sg);
|
|
|
|
|
|
- if ((!req->nbytes) || (!ctx->sg)) {
|
|
|
+ if ((!req->nbytes) || (!ta_ctx->src_sg)) {
|
|
|
/* null data */
|
|
|
src_ptr = NULL;
|
|
|
}
|
|
|
|
|
|
- sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg);
|
|
|
+ sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg);
|
|
|
|
|
|
- sctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
- sctx->dcb_input_data.data_in_size = req->nbytes - (head_len + tail_len);
|
|
|
- sctx->dcb_input_data.app_out_address = NULL;
|
|
|
- sctx->dcb_input_data.block_size = block_size;
|
|
|
- sctx->dcb_input_data.tail_block_size = 0;
|
|
|
- sctx->dcb_input_data.is_applet = 0;
|
|
|
- sctx->dcb_input_data.src_sg = sctx->src_sg;
|
|
|
- sctx->dcb_input_data.dst_sg = NULL;
|
|
|
+ ta_ctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
+ ta_ctx->dcb_input_data.data_in_size =
|
|
|
+ req->nbytes - (head_len + tail_len);
|
|
|
+ ta_ctx->dcb_input_data.app_out_address = NULL;
|
|
|
+ ta_ctx->dcb_input_data.block_size = block_size;
|
|
|
+ ta_ctx->dcb_input_data.tail_block_size = 0;
|
|
|
+ ta_ctx->dcb_input_data.is_applet = 0;
|
|
|
+ ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
|
|
|
+ ta_ctx->dcb_input_data.dst_sg = NULL;
|
|
|
|
|
|
int_error = sep_create_dcb_dmatables_context_kernel(
|
|
|
- sctx->sep_used,
|
|
|
- &sctx->dcb_region,
|
|
|
- &sctx->dmatables_region,
|
|
|
- &sctx->dma_ctx,
|
|
|
- &sctx->dcb_input_data,
|
|
|
+ ta_ctx->sep_used,
|
|
|
+ &ta_ctx->dcb_region,
|
|
|
+ &ta_ctx->dmatables_region,
|
|
|
+ &ta_ctx->dma_ctx,
|
|
|
+ &ta_ctx->dcb_input_data,
|
|
|
1);
|
|
|
if (int_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash update dma table create failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* Construct message to SEP */
|
|
|
- sep_make_header(sctx, &msg_offset, SEP_HASH_UPDATE_OPCODE);
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, SEP_HASH_UPDATE_OPCODE);
|
|
|
|
|
|
msg[0] = (u32)0;
|
|
|
msg[1] = (u32)0;
|
|
|
msg[2] = (u32)0;
|
|
|
|
|
|
- sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
+ sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
&msg_offset, 0);
|
|
|
|
|
|
/* Handle remainders */
|
|
|
|
|
|
/* Head */
|
|
|
- sep_write_msg(sctx, &head_len, sizeof(u32),
|
|
|
+ sep_write_msg(ta_ctx, &head_len, sizeof(u32),
|
|
|
sizeof(u32), &msg_offset, 0);
|
|
|
|
|
|
if (head_len) {
|
|
|
copy_result = sg_copy_to_buffer(
|
|
|
req->src,
|
|
|
- sep_sg_nents(sctx->src_sg),
|
|
|
+ sep_sg_nents(ta_ctx->src_sg),
|
|
|
small_buf, head_len);
|
|
|
|
|
|
if (copy_result != head_len) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sg head copy failure in hash block\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -ENOMEM);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- sep_write_msg(sctx, small_buf, head_len,
|
|
|
+ sep_write_msg(ta_ctx, small_buf, head_len,
|
|
|
sizeof(u32) * 32, &msg_offset, 1);
|
|
|
} else {
|
|
|
msg_offset += sizeof(u32) * 32;
|
|
|
}
|
|
|
|
|
|
/* Tail */
|
|
|
- sep_write_msg(sctx, &tail_len, sizeof(u32),
|
|
|
+ sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
|
|
|
sizeof(u32), &msg_offset, 0);
|
|
|
|
|
|
if (tail_len) {
|
|
|
copy_result = sep_copy_offset_sg(
|
|
|
- sctx->sep_used,
|
|
|
- sctx->src_sg,
|
|
|
+ ta_ctx->sep_used,
|
|
|
+ ta_ctx->src_sg,
|
|
|
req->nbytes - tail_len,
|
|
|
small_buf, tail_len);
|
|
|
|
|
|
if (copy_result != tail_len) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sg tail copy failure in hash block\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -ENOMEM);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- sep_write_msg(sctx, small_buf, tail_len,
|
|
|
+ sep_write_msg(ta_ctx, small_buf, tail_len,
|
|
|
sizeof(u32) * 32, &msg_offset, 1);
|
|
|
} else {
|
|
|
msg_offset += sizeof(u32) * 32;
|
|
|
}
|
|
|
|
|
|
/* Context */
|
|
|
- sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx,
|
|
|
+ sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
|
|
|
sizeof(struct sep_hash_private_context));
|
|
|
|
|
|
- sep_end_msg(sctx, msg_offset);
|
|
|
- sctx->done_with_transaction = 0;
|
|
|
- int_error = sep_crypto_take_sep(sctx);
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
+ are_we_done_yet = 0;
|
|
|
+ int_error = sep_crypto_take_sep(ta_ctx);
|
|
|
if (int_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_update take sep failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sep is now working. Lets wait up to 5 seconds
|
|
|
- * for completion. If it does not complete, we will do
|
|
|
- * a crypto release with -EINVAL to release the
|
|
|
- * kernel crypto infrastructure and let the system
|
|
|
- * continue to boot up
|
|
|
- * We have to wait this long because some crypto
|
|
|
- * operations can take a while
|
|
|
- */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "waiting for done with transaction\n");
|
|
|
-
|
|
|
- sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ);
|
|
|
- while ((time_before(jiffies, sctx->end_time)) &&
|
|
|
- (!sctx->done_with_transaction))
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
|
|
|
schedule();
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "done waiting for done with transaction\n");
|
|
|
-
|
|
|
- /* are we done? */
|
|
|
- if (!sctx->done_with_transaction) {
|
|
|
- /* Nope, lets release and tell crypto no */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "[PID%d] sep_hash_update never finished\n",
|
|
|
- current->pid);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "hash update never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static void sep_hash_final(void *data)
|
|
@@ -2167,63 +2390,53 @@ static void sep_hash_final(void *data)
|
|
|
u32 msg_offset;
|
|
|
struct ahash_request *req;
|
|
|
struct crypto_ahash *tfm;
|
|
|
- struct sep_hash_ctx *ctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
int result;
|
|
|
+ unsigned long end_time;
|
|
|
+ int are_we_done_yet;
|
|
|
|
|
|
req = (struct ahash_request *)data;
|
|
|
tfm = crypto_ahash_reqtfm(req);
|
|
|
- ctx = ahash_request_ctx(req);
|
|
|
sctx = crypto_ahash_ctx(tfm);
|
|
|
+ ta_ctx = ahash_request_ctx(req);
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_final\n");
|
|
|
- sctx->current_hash_stage = HASH_FINISH;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINISH;
|
|
|
+
|
|
|
+ ta_ctx->are_we_done_yet = &are_we_done_yet;
|
|
|
|
|
|
/* opcode and mode */
|
|
|
- sep_make_header(sctx, &msg_offset, SEP_HASH_FINISH_OPCODE);
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, SEP_HASH_FINISH_OPCODE);
|
|
|
|
|
|
/* Context */
|
|
|
- sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx,
|
|
|
+ sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
|
|
|
sizeof(struct sep_hash_private_context));
|
|
|
|
|
|
- sep_end_msg(sctx, msg_offset);
|
|
|
- sctx->done_with_transaction = 0;
|
|
|
- result = sep_crypto_take_sep(sctx);
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
+ are_we_done_yet = 0;
|
|
|
+ result = sep_crypto_take_sep(ta_ctx);
|
|
|
if (result) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_final take sep failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sep is now working. Lets wait up to 5 seconds
|
|
|
- * for completion. If it does not complete, we will do
|
|
|
- * a crypto release with -EINVAL to release the
|
|
|
- * kernel crypto infrastructure and let the system
|
|
|
- * continue to boot up
|
|
|
- * We have to wait this long because some crypto
|
|
|
- * operations can take a while
|
|
|
- */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "waiting for done with transaction\n");
|
|
|
-
|
|
|
- sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ);
|
|
|
- while ((time_before(jiffies, sctx->end_time)) &&
|
|
|
- (!sctx->done_with_transaction))
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
|
|
|
schedule();
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "done waiting for done with transaction\n");
|
|
|
-
|
|
|
- /* are we done? */
|
|
|
- if (!sctx->done_with_transaction) {
|
|
|
- /* Nope, lets release and tell crypto no */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "[PID%d] sep_hash_final never finished\n",
|
|
|
- current->pid);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "hash final job never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static void sep_hash_digest(void *data)
|
|
@@ -2234,6 +2447,7 @@ static void sep_hash_digest(void *data)
|
|
|
u32 msg[10];
|
|
|
size_t copy_result;
|
|
|
int result;
|
|
|
+ int are_we_done_yet;
|
|
|
u32 tail_len;
|
|
|
static char small_buf[100];
|
|
|
struct scatterlist *new_sg;
|
|
@@ -2241,152 +2455,140 @@ static void sep_hash_digest(void *data)
|
|
|
|
|
|
struct ahash_request *req;
|
|
|
struct crypto_ahash *tfm;
|
|
|
- struct sep_hash_ctx *ctx;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
+ unsigned long end_time;
|
|
|
|
|
|
req = (struct ahash_request *)data;
|
|
|
tfm = crypto_ahash_reqtfm(req);
|
|
|
- ctx = ahash_request_ctx(req);
|
|
|
sctx = crypto_ahash_ctx(tfm);
|
|
|
+ ta_ctx = ahash_request_ctx(req);
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_digest\n");
|
|
|
- sctx->current_hash_stage = HASH_DIGEST;
|
|
|
+ ta_ctx->current_hash_stage = HASH_DIGEST;
|
|
|
+
|
|
|
+ ta_ctx->are_we_done_yet = &are_we_done_yet;
|
|
|
|
|
|
/* length for queue status */
|
|
|
- sctx->nbytes = req->nbytes;
|
|
|
+ ta_ctx->nbytes = req->nbytes;
|
|
|
|
|
|
block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
|
|
|
tail_len = req->nbytes % block_size;
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", req->nbytes);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", req->nbytes);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
|
|
|
|
|
|
/* Make sure all pages are even block */
|
|
|
- int_error = sep_oddball_pages(sctx->sep_used, req->src,
|
|
|
+ int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
|
|
|
req->nbytes,
|
|
|
block_size, &new_sg, 1);
|
|
|
|
|
|
if (int_error < 0) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"oddball pages error in crash update\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -ENOMEM);
|
|
|
return;
|
|
|
} else if (int_error == 1) {
|
|
|
- sctx->src_sg = new_sg;
|
|
|
- sctx->src_sg_hold = new_sg;
|
|
|
+ ta_ctx->src_sg = new_sg;
|
|
|
+ ta_ctx->src_sg_hold = new_sg;
|
|
|
} else {
|
|
|
- sctx->src_sg = req->src;
|
|
|
- sctx->src_sg_hold = NULL;
|
|
|
+ ta_ctx->src_sg = req->src;
|
|
|
+ ta_ctx->src_sg_hold = NULL;
|
|
|
}
|
|
|
|
|
|
- src_ptr = sg_virt(sctx->src_sg);
|
|
|
+ src_ptr = sg_virt(ta_ctx->src_sg);
|
|
|
|
|
|
- if ((!req->nbytes) || (!ctx->sg)) {
|
|
|
+ if ((!req->nbytes) || (!ta_ctx->src_sg)) {
|
|
|
/* null data */
|
|
|
src_ptr = NULL;
|
|
|
}
|
|
|
|
|
|
- sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg);
|
|
|
+ sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg);
|
|
|
|
|
|
- sctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
- sctx->dcb_input_data.data_in_size = req->nbytes - tail_len;
|
|
|
- sctx->dcb_input_data.app_out_address = NULL;
|
|
|
- sctx->dcb_input_data.block_size = block_size;
|
|
|
- sctx->dcb_input_data.tail_block_size = 0;
|
|
|
- sctx->dcb_input_data.is_applet = 0;
|
|
|
- sctx->dcb_input_data.src_sg = sctx->src_sg;
|
|
|
- sctx->dcb_input_data.dst_sg = NULL;
|
|
|
+ ta_ctx->dcb_input_data.app_in_address = src_ptr;
|
|
|
+ ta_ctx->dcb_input_data.data_in_size = req->nbytes - tail_len;
|
|
|
+ ta_ctx->dcb_input_data.app_out_address = NULL;
|
|
|
+ ta_ctx->dcb_input_data.block_size = block_size;
|
|
|
+ ta_ctx->dcb_input_data.tail_block_size = 0;
|
|
|
+ ta_ctx->dcb_input_data.is_applet = 0;
|
|
|
+ ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
|
|
|
+ ta_ctx->dcb_input_data.dst_sg = NULL;
|
|
|
|
|
|
int_error = sep_create_dcb_dmatables_context_kernel(
|
|
|
- sctx->sep_used,
|
|
|
- &sctx->dcb_region,
|
|
|
- &sctx->dmatables_region,
|
|
|
- &sctx->dma_ctx,
|
|
|
- &sctx->dcb_input_data,
|
|
|
+ ta_ctx->sep_used,
|
|
|
+ &ta_ctx->dcb_region,
|
|
|
+ &ta_ctx->dmatables_region,
|
|
|
+ &ta_ctx->dma_ctx,
|
|
|
+ &ta_ctx->dcb_input_data,
|
|
|
1);
|
|
|
if (int_error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"hash update dma table create failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* Construct message to SEP */
|
|
|
- sep_make_header(sctx, &msg_offset, SEP_HASH_SINGLE_OPCODE);
|
|
|
- sep_write_msg(sctx, &ctx->hash_opmode,
|
|
|
+ sep_make_header(ta_ctx, &msg_offset, SEP_HASH_SINGLE_OPCODE);
|
|
|
+ sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
|
|
|
sizeof(u32), sizeof(u32), &msg_offset, 0);
|
|
|
|
|
|
msg[0] = (u32)0;
|
|
|
msg[1] = (u32)0;
|
|
|
msg[2] = (u32)0;
|
|
|
|
|
|
- sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
+ sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
|
|
|
&msg_offset, 0);
|
|
|
|
|
|
/* Tail */
|
|
|
- sep_write_msg(sctx, &tail_len, sizeof(u32),
|
|
|
+ sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
|
|
|
sizeof(u32), &msg_offset, 0);
|
|
|
|
|
|
if (tail_len) {
|
|
|
copy_result = sep_copy_offset_sg(
|
|
|
- sctx->sep_used,
|
|
|
- sctx->src_sg,
|
|
|
+ ta_ctx->sep_used,
|
|
|
+ ta_ctx->src_sg,
|
|
|
req->nbytes - tail_len,
|
|
|
small_buf, tail_len);
|
|
|
|
|
|
if (copy_result != tail_len) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sg tail copy failure in hash block\n");
|
|
|
- sep_crypto_release(sctx, -ENOMEM);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -ENOMEM);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- sep_write_msg(sctx, small_buf, tail_len,
|
|
|
+ sep_write_msg(ta_ctx, small_buf, tail_len,
|
|
|
sizeof(u32) * 32, &msg_offset, 1);
|
|
|
} else {
|
|
|
msg_offset += sizeof(u32) * 32;
|
|
|
}
|
|
|
|
|
|
- sep_end_msg(sctx, msg_offset);
|
|
|
+ sep_end_msg(ta_ctx, msg_offset);
|
|
|
|
|
|
- sctx->done_with_transaction = 0;
|
|
|
-
|
|
|
- result = sep_crypto_take_sep(sctx);
|
|
|
+ are_we_done_yet = 0;
|
|
|
+ result = sep_crypto_take_sep(ta_ctx);
|
|
|
if (result) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
+ dev_warn(&ta_ctx->sep_used->pdev->dev,
|
|
|
"sep_hash_digest take sep failed\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Sep is now working. Lets wait up to 5 seconds
|
|
|
- * for completion. If it does not complete, we will do
|
|
|
- * a crypto release with -EINVAL to release the
|
|
|
- * kernel crypto infrastructure and let the system
|
|
|
- * continue to boot up
|
|
|
- * We have to wait this long because some crypto
|
|
|
- * operations can take a while
|
|
|
- */
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "waiting for done with transaction\n");
|
|
|
-
|
|
|
- sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ);
|
|
|
- while ((time_before(jiffies, sctx->end_time)) &&
|
|
|
- (!sctx->done_with_transaction))
|
|
|
+ /* now we sit and wait up to a fixed time for completion */
|
|
|
+ end_time = jiffies + (WAIT_TIME * HZ);
|
|
|
+ while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
|
|
|
schedule();
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev,
|
|
|
- "done waiting for done with transaction\n");
|
|
|
-
|
|
|
- /* are we done? */
|
|
|
- if (!sctx->done_with_transaction) {
|
|
|
- /* Nope, lets release and tell crypto no */
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "[PID%d] sep_hash_digest never finished\n",
|
|
|
- current->pid);
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
+ /* Done waiting; still not done yet? */
|
|
|
+ if (are_we_done_yet == 0) {
|
|
|
+ dev_dbg(&ta_ctx->sep_used->pdev->dev,
|
|
|
+ "hash digest job never got done\n");
|
|
|
+ sep_crypto_release(sctx, ta_ctx, -EINVAL);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -2404,6 +2606,7 @@ static void sep_dequeuer(void *data)
|
|
|
struct ahash_request *hash_req;
|
|
|
struct sep_system_ctx *sctx;
|
|
|
struct crypto_ahash *hash_tfm;
|
|
|
+ struct this_task_ctx *ta_ctx;
|
|
|
|
|
|
|
|
|
this_queue = (struct crypto_queue *)data;
|
|
@@ -2481,22 +2684,32 @@ static void sep_dequeuer(void *data)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (sctx->current_hash_stage == HASH_INIT) {
|
|
|
+ ta_ctx = ahash_request_ctx(hash_req);
|
|
|
+
|
|
|
+ if (ta_ctx->current_hash_stage == HASH_INIT) {
|
|
|
pr_debug("sep crypto queue hash init\n");
|
|
|
sep_hash_init((void *)hash_req);
|
|
|
return;
|
|
|
- } else if (sctx->current_hash_stage == HASH_UPDATE) {
|
|
|
+ } else if (ta_ctx->current_hash_stage == HASH_UPDATE) {
|
|
|
pr_debug("sep crypto queue hash update\n");
|
|
|
sep_hash_update((void *)hash_req);
|
|
|
return;
|
|
|
- } else if (sctx->current_hash_stage == HASH_FINISH) {
|
|
|
+ } else if (ta_ctx->current_hash_stage == HASH_FINISH) {
|
|
|
pr_debug("sep crypto queue hash final\n");
|
|
|
sep_hash_final((void *)hash_req);
|
|
|
return;
|
|
|
- } else if (sctx->current_hash_stage == HASH_DIGEST) {
|
|
|
+ } else if (ta_ctx->current_hash_stage == HASH_DIGEST) {
|
|
|
pr_debug("sep crypto queue hash digest\n");
|
|
|
sep_hash_digest((void *)hash_req);
|
|
|
return;
|
|
|
+ } else if (ta_ctx->current_hash_stage == HASH_FINUP_DATA) {
|
|
|
+ pr_debug("sep crypto queue hash digest\n");
|
|
|
+ sep_hash_update((void *)hash_req);
|
|
|
+ return;
|
|
|
+ } else if (ta_ctx->current_hash_stage == HASH_FINUP_FINISH) {
|
|
|
+ pr_debug("sep crypto queue hash digest\n");
|
|
|
+ sep_hash_final((void *)hash_req);
|
|
|
+ return;
|
|
|
} else {
|
|
|
pr_debug("sep crypto queue hash oops nothing\n");
|
|
|
return;
|
|
@@ -2507,605 +2720,671 @@ static void sep_dequeuer(void *data)
|
|
|
static int sep_sha1_init(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing sha1 init\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 init\n");
|
|
|
- sctx->current_request = SHA1;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA1;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
+ ta_ctx->current_hash_stage = HASH_INIT;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha1 init cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha1 init cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha1_update(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 update\n");
|
|
|
- sctx->current_request = SHA1;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ pr_debug("sep - doing sha1 update\n");
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA1;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
+ ta_ctx->current_hash_stage = HASH_UPDATE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha1 update cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha1 update cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha1_final(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 final\n");
|
|
|
-
|
|
|
- sctx->current_request = SHA1;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
- sctx->current_hash_stage = HASH_FINISH;
|
|
|
-
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha1 final\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA1;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINISH;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha1 final cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha1 final cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha1_digest(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 digest\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha1 digest\n");
|
|
|
|
|
|
- sctx->current_request = SHA1;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
- sctx->current_hash_stage = HASH_DIGEST;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA1;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
+ ta_ctx->current_hash_stage = HASH_DIGEST;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha1 digest cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
+}
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha1 digest cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+static int sep_sha1_finup(struct ahash_request *req)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha1 finup\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA1;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA1;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINUP_DATA;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
+ spin_lock_irq(&queue_lock);
|
|
|
+ error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_md5_init(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 init\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing md5 init\n");
|
|
|
+
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
- sctx->current_request = MD5;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = MD5;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
+ ta_ctx->current_hash_stage = HASH_INIT;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep md5 init cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "md5 init cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_md5_update(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 update\n");
|
|
|
-
|
|
|
- sctx->current_request = MD5;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
- sctx->current_hash_stage = HASH_UPDATE;
|
|
|
-
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing md5 update\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = MD5;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
+ ta_ctx->current_hash_stage = HASH_UPDATE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "md5 update cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "md5 update cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_md5_final(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 final\n");
|
|
|
-
|
|
|
- sctx->current_request = MD5;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
- sctx->current_hash_stage = HASH_FINISH;
|
|
|
-
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing md5 final\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = MD5;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINISH;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep md5 final cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "md5 final cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_md5_digest(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 digest\n");
|
|
|
- sctx->current_request = MD5;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
- sctx->current_hash_stage = HASH_DIGEST;
|
|
|
+ pr_debug("sep - doing md5 digest\n");
|
|
|
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = MD5;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
+ ta_ctx->current_hash_stage = HASH_DIGEST;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep md5 digest cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "md5 digest cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
-static int sep_sha224_init(struct ahash_request *req)
|
|
|
+static int sep_md5_finup(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 init\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing md5 finup\n");
|
|
|
|
|
|
- sctx->current_request = SHA224;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = MD5;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_MD5;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINUP_DATA;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha224 init cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha224 init cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
-static int sep_sha224_update(struct ahash_request *req)
|
|
|
+static int sep_sha224_init(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 update\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha224 init\n");
|
|
|
+
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
- sctx->current_request = SHA224;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
- sctx->current_hash_stage = HASH_UPDATE;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA224;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
+ ta_ctx->current_hash_stage = HASH_INIT;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
+
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
+}
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha224 update cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
+static int sep_sha224_update(struct ahash_request *req)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha224 update\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA224;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
+ ta_ctx->current_hash_stage = HASH_UPDATE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
+ spin_lock_irq(&queue_lock);
|
|
|
+ error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha224 update cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha224_final(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 final\n");
|
|
|
-
|
|
|
- sctx->current_request = SHA224;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
- sctx->current_hash_stage = HASH_FINISH;
|
|
|
-
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha224 final\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA224;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINISH;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha224 final cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha224 final cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha224_digest(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing sha224 digest\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing 224 digest\n");
|
|
|
- sctx->current_request = SHA224;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
- sctx->current_hash_stage = HASH_DIGEST;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA224;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
+ ta_ctx->current_hash_stage = HASH_DIGEST;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha224 digest cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha256 digest cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
-static int sep_sha256_init(struct ahash_request *req)
|
|
|
+static int sep_sha224_finup(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 init\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing sha224 finup\n");
|
|
|
|
|
|
- sctx->current_request = SHA256;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
- sctx->current_hash_stage = HASH_INIT;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA224;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA224;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINUP_DATA;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha256 init cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha256 init cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
-static int sep_sha256_update(struct ahash_request *req)
|
|
|
+static int sep_sha256_init(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 update\n");
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha256 init\n");
|
|
|
+
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
- sctx->current_request = SHA256;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
- sctx->current_hash_stage = HASH_UPDATE;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA256;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
+ ta_ctx->current_hash_stage = HASH_INIT;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
+
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
+}
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha256 update cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
+static int sep_sha256_update(struct ahash_request *req)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha256 update\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA256;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
+ ta_ctx->current_hash_stage = HASH_UPDATE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
+ spin_lock_irq(&queue_lock);
|
|
|
+ error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha256 update cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha256_final(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 final\n");
|
|
|
-
|
|
|
- sctx->current_request = SHA256;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
- sctx->current_hash_stage = HASH_FINISH;
|
|
|
-
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+ pr_debug("sep - doing sha256 final\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA256;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINISH;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha256 final cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha256 final cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_sha256_digest(struct ahash_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
|
|
- struct sep_hash_ctx *ctx = ahash_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing sha256 digest\n");
|
|
|
+
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 digest\n");
|
|
|
- sctx->current_request = SHA256;
|
|
|
- sctx->current_hash_req = req;
|
|
|
- sctx->current_cypher_req = NULL;
|
|
|
- ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
- sctx->current_hash_stage = HASH_DIGEST;
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA256;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
+ ta_ctx->current_hash_stage = HASH_DIGEST;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
+
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
+}
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep sha256 digest cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
+static int sep_sha256_finup(struct ahash_request *req)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sha256 digest cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ pr_debug("sep - doing sha256 finup\n");
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = SHA256;
|
|
|
+ ta_ctx->current_hash_req = req;
|
|
|
+ ta_ctx->current_cypher_req = NULL;
|
|
|
+ ta_ctx->hash_opmode = SEP_HASH_SHA256;
|
|
|
+ ta_ctx->current_hash_stage = HASH_FINUP_DATA;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
+ spin_lock_irq(&queue_lock);
|
|
|
+ error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
+
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_crypto_init(struct crypto_tfm *tfm)
|
|
|
{
|
|
|
- struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm);
|
|
|
const char *alg_name = crypto_tfm_alg_name(tfm);
|
|
|
|
|
|
- sctx->sep_used = sep_dev;
|
|
|
-
|
|
|
if (alg_name == NULL)
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "alg is NULL\n");
|
|
|
+ pr_debug("sep_crypto_init alg is NULL\n");
|
|
|
else
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "alg is %s\n", alg_name);
|
|
|
+ pr_debug("sep_crypto_init alg is %s\n", alg_name);
|
|
|
|
|
|
- tfm->crt_ablkcipher.reqsize = sizeof(struct sep_block_ctx);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_init\n");
|
|
|
+ tfm->crt_ablkcipher.reqsize = sizeof(struct this_task_ctx);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static void sep_crypto_exit(struct crypto_tfm *tfm)
|
|
|
{
|
|
|
- struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm);
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_exit\n");
|
|
|
- sctx->sep_used = NULL;
|
|
|
+ pr_debug("sep_crypto_exit\n");
|
|
|
}
|
|
|
|
|
|
static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
@@ -3113,8 +3392,9 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
{
|
|
|
struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm);
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep aes setkey\n");
|
|
|
+ pr_debug("sep aes setkey\n");
|
|
|
|
|
|
+ pr_debug("tfm is %p sctx is %p\n", tfm, sctx);
|
|
|
switch (keylen) {
|
|
|
case SEP_AES_KEY_128_SIZE:
|
|
|
sctx->aes_key_size = AES_128;
|
|
@@ -3129,7 +3409,7 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
sctx->aes_key_size = AES_512;
|
|
|
break;
|
|
|
default:
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "sep aes key size %x\n",
|
|
|
+ pr_debug("invalid sep aes key size %x\n",
|
|
|
keylen);
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -3140,7 +3420,6 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
sctx->keylen = keylen;
|
|
|
/* Indicate to encrypt/decrypt function to send key to SEP */
|
|
|
sctx->key_sent = 0;
|
|
|
- sctx->last_block = 0;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3148,153 +3427,159 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
static int sep_aes_ecb_encrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing aes ecb encrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb encrypt\n");
|
|
|
- sctx->current_request = AES_ECB;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->aes_encmode = SEP_AES_ENCRYPT;
|
|
|
- bctx->aes_opmode = SEP_AES_ECB;
|
|
|
- bctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = AES_ECB;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
|
|
|
+ ta_ctx->aes_opmode = SEP_AES_ECB;
|
|
|
+ ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_ecb_encrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_ecb_encrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_aes_ecb_decrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing aes ecb decrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb decrypt\n");
|
|
|
- sctx->current_request = AES_ECB;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->aes_encmode = SEP_AES_DECRYPT;
|
|
|
- bctx->aes_opmode = SEP_AES_ECB;
|
|
|
- bctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = AES_ECB;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->aes_encmode = SEP_AES_DECRYPT;
|
|
|
+ ta_ctx->aes_opmode = SEP_AES_ECB;
|
|
|
+ ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_ecb_decrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_ecb_decrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_aes_cbc_encrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
crypto_ablkcipher_reqtfm(req));
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc encrypt\n");
|
|
|
- sctx->current_request = AES_CBC;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->aes_encmode = SEP_AES_ENCRYPT;
|
|
|
- bctx->aes_opmode = SEP_AES_CBC;
|
|
|
- bctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+ pr_debug("sep - doing aes cbc encrypt\n");
|
|
|
+
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
+
|
|
|
+ pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
|
|
|
+ crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = AES_CBC;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
|
|
|
+ ta_ctx->aes_opmode = SEP_AES_CBC;
|
|
|
+ ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_cbc_encrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_cbc_encrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_aes_cbc_decrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
crypto_ablkcipher_reqtfm(req));
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc decrypt\n");
|
|
|
- sctx->current_request = AES_CBC;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->aes_encmode = SEP_AES_DECRYPT;
|
|
|
- bctx->aes_opmode = SEP_AES_CBC;
|
|
|
- bctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+ pr_debug("sep - doing aes cbc decrypt\n");
|
|
|
+
|
|
|
+ pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
|
|
|
+ crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
|
|
|
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
+
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = AES_CBC;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->aes_encmode = SEP_AES_DECRYPT;
|
|
|
+ ta_ctx->aes_opmode = SEP_AES_CBC;
|
|
|
+ ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_cbc_decrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_aes_cbc_decrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
@@ -3304,7 +3589,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm);
|
|
|
u32 *flags = &ctfm->crt_flags;
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep des setkey\n");
|
|
|
+ pr_debug("sep des setkey\n");
|
|
|
|
|
|
switch (keylen) {
|
|
|
case DES_KEY_SIZE:
|
|
@@ -3317,7 +3602,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
sctx->des_nbr_keys = DES_KEY_3;
|
|
|
break;
|
|
|
default:
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "invalid key size %x\n",
|
|
|
+ pr_debug("invalid key size %x\n",
|
|
|
keylen);
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -3326,7 +3611,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
(sep_weak_key(key, keylen))) {
|
|
|
|
|
|
*flags |= CRYPTO_TFM_RES_WEAK_KEY;
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev, "weak key\n");
|
|
|
+ pr_debug("weak key\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -3335,7 +3620,6 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
sctx->keylen = keylen;
|
|
|
/* Indicate to encrypt/decrypt function to send key to SEP */
|
|
|
sctx->key_sent = 0;
|
|
|
- sctx->last_block = 0;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3343,153 +3627,149 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
|
|
static int sep_des_ebc_encrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing des ecb encrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb encrypt\n");
|
|
|
- sctx->current_request = DES_ECB;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->des_encmode = SEP_DES_ENCRYPT;
|
|
|
- bctx->des_opmode = SEP_DES_ECB;
|
|
|
- bctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = DES_ECB;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->des_encmode = SEP_DES_ENCRYPT;
|
|
|
+ ta_ctx->des_opmode = SEP_DES_ECB;
|
|
|
+ ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_ecb_encrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_ecb_encrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_des_ebc_decrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing des ecb decrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb decrypt\n");
|
|
|
- sctx->current_request = DES_ECB;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->des_encmode = SEP_DES_DECRYPT;
|
|
|
- bctx->des_opmode = SEP_DES_ECB;
|
|
|
- bctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = DES_ECB;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->des_encmode = SEP_DES_DECRYPT;
|
|
|
+ ta_ctx->des_opmode = SEP_DES_ECB;
|
|
|
+ ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_ecb_decrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_ecb_decrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_des_cbc_encrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing des cbc encrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc encrypt\n");
|
|
|
- sctx->current_request = DES_CBC;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->des_encmode = SEP_DES_ENCRYPT;
|
|
|
- bctx->des_opmode = SEP_DES_CBC;
|
|
|
- bctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = DES_CBC;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->des_encmode = SEP_DES_ENCRYPT;
|
|
|
+ ta_ctx->des_opmode = SEP_DES_CBC;
|
|
|
+ ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_cbc_encrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_cbc_encrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static int sep_des_cbc_decrypt(struct ablkcipher_request *req)
|
|
|
{
|
|
|
int error;
|
|
|
- struct sep_block_ctx *bctx = ablkcipher_request_ctx(req);
|
|
|
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
|
|
|
- crypto_ablkcipher_reqtfm(req));
|
|
|
+ int error1;
|
|
|
+ struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
|
|
|
+
|
|
|
+ pr_debug("sep - doing des ecb decrypt\n");
|
|
|
|
|
|
- dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc decrypt\n");
|
|
|
- sctx->current_request = DES_CBC;
|
|
|
- sctx->current_hash_req = NULL;
|
|
|
- sctx->current_cypher_req = req;
|
|
|
- bctx->des_encmode = SEP_DES_DECRYPT;
|
|
|
- bctx->des_opmode = SEP_DES_CBC;
|
|
|
- bctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
- bctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+ /* Clear out task context */
|
|
|
+ memset(ta_ctx, 0, sizeof(struct this_task_ctx));
|
|
|
|
|
|
+ ta_ctx->sep_used = sep_dev;
|
|
|
+ ta_ctx->current_request = DES_CBC;
|
|
|
+ ta_ctx->current_hash_req = NULL;
|
|
|
+ ta_ctx->current_cypher_req = req;
|
|
|
+ ta_ctx->des_encmode = SEP_DES_DECRYPT;
|
|
|
+ ta_ctx->des_opmode = SEP_DES_CBC;
|
|
|
+ ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
|
|
|
+ ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
|
|
|
+
|
|
|
+ /* lock necessary so that only one entity touches the queues */
|
|
|
spin_lock_irq(&queue_lock);
|
|
|
error = crypto_enqueue_request(&sep_queue, &req->base);
|
|
|
- spin_unlock_irq(&queue_lock);
|
|
|
-
|
|
|
- if ((error != 0) && (error != -EINPROGRESS)) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_cbc_decrypt cant enqueue\n");
|
|
|
- sep_crypto_release(sctx, error);
|
|
|
- return error;
|
|
|
- }
|
|
|
|
|
|
- error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer,
|
|
|
- (void *)&sep_queue);
|
|
|
- if (error) {
|
|
|
- dev_warn(&sctx->sep_used->pdev->dev,
|
|
|
- "sep_des_cbc_decrypt cannot submit queue\n");
|
|
|
- sep_crypto_release(sctx, -EINVAL);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return -EINPROGRESS;
|
|
|
+ if ((error != 0) && (error != -EINPROGRESS))
|
|
|
+ pr_debug(" sep - crypto enqueue failed: %x\n",
|
|
|
+ error);
|
|
|
+ error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
|
|
|
+ sep_dequeuer, (void *)&sep_queue);
|
|
|
+ if (error1)
|
|
|
+ pr_debug(" sep - workqueue submit failed: %x\n",
|
|
|
+ error1);
|
|
|
+ spin_unlock_irq(&queue_lock);
|
|
|
+ /* We return result of crypto enqueue */
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
static struct ahash_alg hash_algs[] = {
|
|
@@ -3498,6 +3778,7 @@ static struct ahash_alg hash_algs[] = {
|
|
|
.update = sep_sha1_update,
|
|
|
.final = sep_sha1_final,
|
|
|
.digest = sep_sha1_digest,
|
|
|
+ .finup = sep_sha1_finup,
|
|
|
.halg = {
|
|
|
.digestsize = SHA1_DIGEST_SIZE,
|
|
|
.base = {
|
|
@@ -3520,6 +3801,7 @@ static struct ahash_alg hash_algs[] = {
|
|
|
.update = sep_md5_update,
|
|
|
.final = sep_md5_final,
|
|
|
.digest = sep_md5_digest,
|
|
|
+ .finup = sep_md5_finup,
|
|
|
.halg = {
|
|
|
.digestsize = MD5_DIGEST_SIZE,
|
|
|
.base = {
|
|
@@ -3542,6 +3824,7 @@ static struct ahash_alg hash_algs[] = {
|
|
|
.update = sep_sha224_update,
|
|
|
.final = sep_sha224_final,
|
|
|
.digest = sep_sha224_digest,
|
|
|
+ .finup = sep_sha224_finup,
|
|
|
.halg = {
|
|
|
.digestsize = SHA224_DIGEST_SIZE,
|
|
|
.base = {
|
|
@@ -3564,6 +3847,7 @@ static struct ahash_alg hash_algs[] = {
|
|
|
.update = sep_sha256_update,
|
|
|
.final = sep_sha256_final,
|
|
|
.digest = sep_sha256_digest,
|
|
|
+ .finup = sep_sha256_finup,
|
|
|
.halg = {
|
|
|
.digestsize = SHA256_DIGEST_SIZE,
|
|
|
.base = {
|
|
@@ -3621,6 +3905,7 @@ static struct crypto_alg crypto_algs[] = {
|
|
|
.max_keysize = AES_MAX_KEY_SIZE,
|
|
|
.setkey = sep_aes_setkey,
|
|
|
.encrypt = sep_aes_cbc_encrypt,
|
|
|
+ .ivsize = AES_BLOCK_SIZE,
|
|
|
.decrypt = sep_aes_cbc_decrypt,
|
|
|
}
|
|
|
},
|
|
@@ -3661,6 +3946,7 @@ static struct crypto_alg crypto_algs[] = {
|
|
|
.max_keysize = DES_KEY_SIZE,
|
|
|
.setkey = sep_des_setkey,
|
|
|
.encrypt = sep_des_cbc_encrypt,
|
|
|
+ .ivsize = DES_BLOCK_SIZE,
|
|
|
.decrypt = sep_des_cbc_decrypt,
|
|
|
}
|
|
|
},
|
|
@@ -3714,7 +4000,8 @@ int sep_crypto_setup(void)
|
|
|
|
|
|
crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH);
|
|
|
|
|
|
- sep_dev->workqueue = create_workqueue("sep_crypto_workqueue");
|
|
|
+ sep_dev->workqueue = create_singlethread_workqueue(
|
|
|
+ "sep_crypto_workqueue");
|
|
|
if (!sep_dev->workqueue) {
|
|
|
dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n");
|
|
|
return -ENOMEM;
|
|
@@ -3723,7 +4010,6 @@ int sep_crypto_setup(void)
|
|
|
i = 0;
|
|
|
j = 0;
|
|
|
|
|
|
- spin_lock_init(&sep_dev->busy_lock);
|
|
|
spin_lock_init(&queue_lock);
|
|
|
|
|
|
err = 0;
|