crypto: fix chained buffer integrity support
[vpp.git] / src / plugins / crypto_sw_scheduler / main.c
index a450bc1..fa2611f 100644 (file)
@@ -88,10 +88,8 @@ crypto_sw_scheduler_frame_enqueue (vlib_main_t * vm,
       u32 n_elts = frame->n_elts, i;
       for (i = 0; i < n_elts; i++)
        frame->elts[i].status = VNET_CRYPTO_OP_STATUS_FAIL_ENGINE_ERR;
-      frame->state = VNET_CRYPTO_FRAME_STATE_ELT_ERROR;
       return -1;
     }
-  frame->state = VNET_CRYPTO_FRAME_STATE_NOT_PROCESSED;
   q->jobs[head & CRYPTO_SW_SCHEDULER_QUEUE_MASK] = frame;
   head += 1;
   CLIB_MEMORY_STORE_BARRIER ();
@@ -150,8 +148,6 @@ cryptodev_sw_scheduler_sgl (vlib_main_t * vm,
   u32 n_chunks = 0;
   u32 chunk_index = vec_len (ptd->chunks);
 
-  op->flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
-
   while (len)
     {
       if (nb->current_data + nb->current_length > offset)
@@ -174,7 +170,21 @@ cryptodev_sw_scheduler_sgl (vlib_main_t * vm,
        break;
     }
 
-  ASSERT (offset == 0 && len == 0);
+  ASSERT (offset == 0);
+  if (n_chunks && len)
+    {
+      /* Some async crypto users can use buffers in creative ways, let's allow
+       * some flexibility here...
+       * Current example is ESP decrypt with ESN in async mode: it will stash
+       * ESN at the end of the last buffer (if it can) because it must be part
+       * of the integrity check but it will not update the buffer length.
+       * Fixup the last operation chunk length if we have room.
+       */
+      ASSERT (vlib_buffer_space_left_at_end (vm, nb) >= len);
+      if (vlib_buffer_space_left_at_end (vm, nb) >= len)
+       ch->len += len;
+    }
+
   op->chunk_index = chunk_index;
   op->n_chunks = n_chunks;
 }
@@ -253,14 +263,12 @@ crypto_sw_scheduler_convert_link_crypto (vlib_main_t * vm,
   crypto_op->iv = fe->iv;
   crypto_op->key_index = key->index_crypto;
   crypto_op->user_data = 0;
+  crypto_op->flags = fe->flags & ~VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
   integ_op->op = integ_op_id;
   integ_op->digest = fe->digest;
   integ_op->digest_len = digest_len;
   integ_op->key_index = key->index_integ;
-  if (is_enc)
-    crypto_op->flags |= VNET_CRYPTO_OP_FLAG_INIT_IV;
-  else
-    integ_op->flags |= VNET_CRYPTO_OP_FLAG_HMAC_CHECK;
+  integ_op->flags = fe->flags & ~VNET_CRYPTO_OP_FLAG_INIT_IV;
   crypto_op->user_data = integ_op->user_data = index;
 }
 
@@ -543,7 +551,7 @@ sw_scheduler_show_workers (vlib_main_t * vm, unformat_input_t * input,
   u32 i;
 
   vlib_cli_output (vm, "%-7s%-20s%-8s", "ID", "Name", "Crypto");
-  for (i = vlib_num_workers () >= 0; i < vlib_thread_main.n_vlib_mains; i++)
+  for (i = 1; i < vlib_thread_main.n_vlib_mains; i++)
     {
       vlib_cli_output (vm, "%-7d%-20s%-8s", vlib_get_worker_index (i),
                       (vlib_worker_threads + i)->name,