-always_inline void
-ipsecmb_retire_gcm_cipher_job (JOB_AES_HMAC * job,
- u32 * n_fail, JOB_CIPHER_DIRECTION direction)
-{
- vnet_crypto_op_t *op = job->user_data;
-
- if (STS_COMPLETED != job->status)
- {
- op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
- *n_fail = *n_fail + 1;
- return;
- }
- else
- op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
-
- if (DECRYPT == direction)
- {
- if ((memcmp (op->tag, job->auth_tag_output, op->tag_len)))
- {
- *n_fail = *n_fail + 1;
- op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
- }
- }
-}
-
-static_always_inline u32
-ipsecmb_ops_gcm_cipher_inline (vlib_main_t * vm, vnet_crypto_op_t * ops[],
- u32 n_ops, u32 key_len,
- JOB_CIPHER_DIRECTION direction)
-{
- ipsecmb_main_t *imbm = &ipsecmb_main;
- ipsecmb_per_thread_data_t *ptd = vec_elt_at_index (imbm->per_thread_data,
- vm->thread_index);
- JOB_AES_HMAC *job;
- u32 i, n_fail = 0;
- u8 scratch[n_ops][64];
-
- /*
- * queue all the jobs first ...
- */
- for (i = 0; i < n_ops; i++)
- {
- struct gcm_key_data *kd;
- vnet_crypto_op_t *op = ops[i];
- kd = (struct gcm_key_data *) imbm->key_data[op->key_index];
-
- job = IMB_GET_NEXT_JOB (ptd->mgr);
-
- job->src = op->src;
- job->dst = op->dst;
- job->msg_len_to_cipher_in_bytes = op->len;
- job->cipher_start_src_offset_in_bytes = 0;
-
- job->hash_alg = AES_GMAC;
- job->cipher_mode = GCM;
- job->cipher_direction = direction;
- job->chain_order = (direction == ENCRYPT ? CIPHER_HASH : HASH_CIPHER);
-
- job->iv = op->iv;
- job->aes_key_len_in_bytes = key_len / 8;
- job->aes_enc_key_expanded = kd;
- job->aes_dec_key_expanded = kd;
- job->iv_len_in_bytes = 12;
-
- job->u.GCM.aad = op->aad;
- job->u.GCM.aad_len_in_bytes = op->aad_len;
- job->auth_tag_output_len_in_bytes = op->tag_len;
- if (DECRYPT == direction)
- job->auth_tag_output = scratch[i];
- else
- job->auth_tag_output = op->tag;
- job->user_data = op;
-
- job = IMB_SUBMIT_JOB (ptd->mgr);
-
- if (job)
- ipsecmb_retire_gcm_cipher_job (job, &n_fail, direction);
- }
-
- while ((job = IMB_FLUSH_JOB (ptd->mgr)))
- ipsecmb_retire_gcm_cipher_job (job, &n_fail, direction);
-
- return n_ops - n_fail;
-}
-