Example #1
0
/* Basic algorithm run function for async inplace mode.
 * Creates a session from input parameters and runs one operation
 * on input_vec. Checks the output of the crypto operation against
 * output_vec. Operation completion event is dequeued polling the
 * session output queue. Completion context pointer is retrieved
 * and checked against the one set before the operation.
 * Completion event can be a separate buffer or the input packet
 * buffer can be used.
 * */
static void alg_test(odp_crypto_op_t op,
		     odp_cipher_alg_t cipher_alg,
		     odp_crypto_iv_t ses_iv,
		     uint8_t *op_iv_ptr,
		     odp_crypto_key_t cipher_key,
		     odp_auth_alg_t auth_alg,
		     odp_crypto_key_t auth_key,
		     odp_crypto_data_range_t *cipher_range,
		     odp_crypto_data_range_t *auth_range,
		     const uint8_t *plaintext,
		     unsigned int plaintext_len,
		     const uint8_t *ciphertext,
		     unsigned int ciphertext_len,
		     const uint8_t *digest,
		     unsigned int digest_len
		     )
{
	odp_crypto_session_t session;
	int rc;
	odp_crypto_ses_create_err_t status;
	odp_bool_t posted;
	odp_event_t event;
	odp_crypto_compl_t compl_event;
	odp_crypto_op_result_t result;

	/* Create a crypto session */
	odp_crypto_session_params_t ses_params;
	memset(&ses_params, 0, sizeof(ses_params));
	ses_params.op = op;
	ses_params.auth_cipher_text = false;
	ses_params.pref_mode = suite_context.pref_mode;
	ses_params.cipher_alg = cipher_alg;
	ses_params.auth_alg = auth_alg;
	ses_params.compl_queue = suite_context.queue;
	ses_params.output_pool = suite_context.pool;
	ses_params.cipher_key = cipher_key;
	ses_params.iv = ses_iv;
	ses_params.auth_key = auth_key;

	rc = odp_crypto_session_create(&ses_params, &session, &status);
	CU_ASSERT_FATAL(!rc);
	CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
	CU_ASSERT(odp_crypto_session_to_u64(session) !=
		  odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID));

	/* Prepare input data */
	odp_packet_t pkt = odp_packet_alloc(suite_context.pool,
					    plaintext_len + digest_len);
	CU_ASSERT(pkt != ODP_PACKET_INVALID);
	uint8_t *data_addr = odp_packet_data(pkt);
	memcpy(data_addr, plaintext, plaintext_len);
	int data_off = 0;

	/* Prepare input/output params */
	odp_crypto_op_params_t op_params;
	memset(&op_params, 0, sizeof(op_params));
	op_params.session = session;
	op_params.pkt = pkt;
	op_params.out_pkt = pkt;
	op_params.ctx = (void *)0xdeadbeef;

	if (cipher_range) {
		op_params.cipher_range = *cipher_range;
		data_off = cipher_range->offset;
	} else {
		op_params.cipher_range.offset = data_off;
		op_params.cipher_range.length = plaintext_len;
	}
	if (auth_range) {
		op_params.auth_range = *auth_range;
	} else {
		op_params.auth_range.offset = data_off;
		op_params.auth_range.length = plaintext_len;
	}
	if (op_iv_ptr)
		op_params.override_iv_ptr = op_iv_ptr;

	op_params.hash_result_offset = plaintext_len;

	rc = odp_crypto_operation(&op_params, &posted, &result);
	if (rc < 0) {
		CU_FAIL("Failed odp_crypto_operation()");
		goto cleanup;
	}

	if (posted) {
		/* Poll completion queue for results */
		do {
			event = odp_queue_deq(suite_context.queue);
		} while (event == ODP_EVENT_INVALID);

		compl_event = odp_crypto_compl_from_event(event);
		CU_ASSERT(odp_crypto_compl_to_u64(compl_event) ==
			  odp_crypto_compl_to_u64(odp_crypto_compl_from_event(event)));
		odp_crypto_compl_result(compl_event, &result);
		odp_crypto_compl_free(compl_event);
	}

	CU_ASSERT(result.ok);
	CU_ASSERT(result.pkt == pkt);

	if (cipher_alg != ODP_CIPHER_ALG_NULL) { 
		CU_ASSERT(!memcmp(data_addr, ciphertext, ciphertext_len));
    if (memcmp(data_addr, ciphertext, ciphertext_len)) {
      printf("data:\n");
      unsigned j;
      for (j = 0; j < ciphertext_len; ++j) printf("%02x ", data_addr[j]);
      printf("\ncipher: \n");
      for (j = 0; j < ciphertext_len; ++j) printf("%02x ", ciphertext[j]);
      printf("\n\n");
    };
  };

	if (op == ODP_CRYPTO_OP_ENCODE && auth_alg != ODP_AUTH_ALG_NULL)
		CU_ASSERT(!memcmp(data_addr + op_params.hash_result_offset,
				  digest, digest_len));

	CU_ASSERT(result.ctx == (void *)0xdeadbeef);
cleanup:
	rc = odp_crypto_session_destroy(session);
	CU_ASSERT(!rc);

	odp_packet_free(pkt);
}
Example #2
0
/* Basic algorithm run function for async inplace mode.
 * Creates a session from input parameters and runs one operation
 * on input_vec. Checks the output of the crypto operation against
 * output_vec. Operation completion event is dequeued polling the
 * session output queue. Completion context pointer is retrieved
 * and checked against the one set before the operation.
 * Completion event can be a separate buffer or the input packet
 * buffer can be used.
 * */
static void alg_test(enum odp_crypto_op op,
		     enum odp_cipher_alg cipher_alg,
		     odp_crypto_iv_t ses_iv,
		     uint8_t *op_iv_ptr,
		     odp_crypto_key_t cipher_key,
		     enum odp_auth_alg auth_alg,
		     odp_crypto_key_t auth_key,
		     uint8_t *input_vec,
		     unsigned int input_vec_len,
		     uint8_t *output_vec,
		     unsigned int output_vec_len)
{
	odp_crypto_session_t session;
	int rc;
	enum odp_crypto_ses_create_err status;
	odp_bool_t posted;
	odp_event_t event;
	odp_crypto_compl_t compl_event;
	odp_crypto_op_result_t result;

	/* Create a crypto session */
	odp_crypto_session_params_t ses_params;
	memset(&ses_params, 0, sizeof(ses_params));
	ses_params.op = op;
	ses_params.auth_cipher_text = false;
	ses_params.pref_mode = suite_context.pref_mode;
	ses_params.cipher_alg = cipher_alg;
	ses_params.auth_alg = auth_alg;
	ses_params.compl_queue = suite_context.queue;
	ses_params.output_pool = suite_context.pool;
	ses_params.cipher_key = cipher_key;
	ses_params.iv = ses_iv;
	ses_params.auth_key = auth_key;

	rc = odp_crypto_session_create(&ses_params, &session, &status);
	CU_ASSERT(!rc);
	CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE);
	CU_ASSERT(odp_crypto_session_to_u64(session) !=
		  odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID));

	/* Prepare input data */
	odp_packet_t pkt = odp_packet_alloc(suite_context.pool, input_vec_len);
	CU_ASSERT(pkt != ODP_PACKET_INVALID);
	uint8_t *data_addr = odp_packet_data(pkt);
	memcpy(data_addr, input_vec, input_vec_len);
	const int data_off = 0;

	/* Prepare input/output params */
	odp_crypto_op_params_t op_params;
	memset(&op_params, 0, sizeof(op_params));
	op_params.session = session;
	op_params.pkt = pkt;
	op_params.out_pkt = pkt;
	op_params.ctx = (void *)0xdeadbeef;
	if (cipher_alg != ODP_CIPHER_ALG_NULL &&
	    auth_alg == ODP_AUTH_ALG_NULL) {
		op_params.cipher_range.offset = data_off;
		op_params.cipher_range.length = input_vec_len;
		if (op_iv_ptr)
			op_params.override_iv_ptr = op_iv_ptr;
	} else if (cipher_alg == ODP_CIPHER_ALG_NULL &&
		 auth_alg != ODP_AUTH_ALG_NULL) {
		op_params.auth_range.offset = data_off;
		op_params.auth_range.length = input_vec_len;
		op_params.hash_result_offset = data_off;
	} else {
		CU_FAIL("%s : not implemented for combined alg mode\n");
	}

	rc = odp_crypto_operation(&op_params, &posted, &result);
	if (rc < 0) {
		CU_FAIL("Failed odp_crypto_operation()");
		goto cleanup;
	}

	if (posted) {
		/* Poll completion queue for results */
		do {
			event = odp_queue_deq(suite_context.queue);
		} while (event == ODP_EVENT_INVALID);

		compl_event = odp_crypto_compl_from_event(event);
		CU_ASSERT(odp_crypto_compl_to_u64(compl_event) ==
			  odp_crypto_compl_to_u64(odp_crypto_compl_from_event(event)));
		odp_crypto_compl_result(compl_event, &result);
		odp_crypto_compl_free(compl_event);
	}

	CU_ASSERT(result.ok);
	CU_ASSERT(result.pkt == pkt);

	CU_ASSERT(!memcmp(data_addr, output_vec, output_vec_len));

	CU_ASSERT(result.ctx == (void *)0xdeadbeef);
cleanup:
	rc = odp_crypto_session_destroy(session);
	CU_ASSERT(!rc);

	odp_packet_free(pkt);
}
Example #3
0
int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa,
			     sa_db_entry_t *auth_sa,
			     tun_db_entry_t *tun,
			     crypto_api_mode_e api_mode,
			     odp_bool_t in,
			     odp_queue_t completionq,
			     odp_pool_t out_pool)
{
	odp_crypto_session_params_t params;
	ipsec_cache_entry_t *entry;
	odp_crypto_ses_create_err_t ses_create_rc;
	odp_crypto_session_t session;
	sa_mode_t mode = IPSEC_SA_MODE_TRANSPORT;

	/* Verify we have a good entry */
	entry = &ipsec_cache->array[ipsec_cache->index];
	if (MAX_DB <= ipsec_cache->index)
		return -1;

	/* Verify SA mode match in case of cipher&auth */
	if (cipher_sa && auth_sa &&
	    (cipher_sa->mode != auth_sa->mode))
		return -1;

	/* Setup parameters and call crypto library to create session */
	params.op = (in) ? ODP_CRYPTO_OP_DECODE : ODP_CRYPTO_OP_ENCODE;
	params.auth_cipher_text = TRUE;
	if (CRYPTO_API_SYNC == api_mode) {
		params.pref_mode   = ODP_CRYPTO_SYNC;
		params.compl_queue = ODP_QUEUE_INVALID;
		params.output_pool = ODP_POOL_INVALID;
	} else {
		params.pref_mode   = ODP_CRYPTO_ASYNC;
		params.compl_queue = completionq;
		params.output_pool = out_pool;
	}

	if (CRYPTO_API_ASYNC_NEW_BUFFER == api_mode)
		entry->in_place = FALSE;
	else
		entry->in_place = TRUE;

	/* Cipher */
	if (cipher_sa) {
		params.cipher_alg  = cipher_sa->alg.u.cipher;
		params.cipher_key.data  = cipher_sa->key.data;
		params.cipher_key.length  = cipher_sa->key.length;
		params.iv.data = entry->state.iv;
		params.iv.length = cipher_sa->iv_len;
		mode = cipher_sa->mode;
	} else {
		params.cipher_alg = ODP_CIPHER_ALG_NULL;
		params.iv.data = NULL;
		params.iv.length = 0;
	}

	/* Auth */
	if (auth_sa) {
		params.auth_alg = auth_sa->alg.u.auth;
		params.auth_key.data = auth_sa->key.data;
		params.auth_key.length = auth_sa->key.length;
		mode = auth_sa->mode;
	} else {
		params.auth_alg = ODP_AUTH_ALG_NULL;
	}

	/* Generate an IV */
	if (params.iv.length) {
		int32_t size = params.iv.length;

		int32_t ret = odp_random_data(params.iv.data, size, 1);

		if (ret != size)
			return -1;
	}

	/* Synchronous session create for now */
	if (odp_crypto_session_create(&params, &session, &ses_create_rc))
		return -1;
	if (ODP_CRYPTO_SES_CREATE_ERR_NONE != ses_create_rc)
		return -1;

	/* Copy remainder */
	if (cipher_sa) {
		entry->src_ip = cipher_sa->src_ip;
		entry->dst_ip = cipher_sa->dst_ip;
		entry->esp.alg = cipher_sa->alg.u.cipher;
		entry->esp.spi = cipher_sa->spi;
		entry->esp.block_len = cipher_sa->block_len;
		entry->esp.iv_len = cipher_sa->iv_len;
		memcpy(&entry->esp.key, &cipher_sa->key, sizeof(ipsec_key_t));
	}
	if (auth_sa) {
		entry->src_ip = auth_sa->src_ip;
		entry->dst_ip = auth_sa->dst_ip;
		entry->ah.alg = auth_sa->alg.u.auth;
		entry->ah.spi = auth_sa->spi;
		entry->ah.icv_len = auth_sa->icv_len;
		memcpy(&entry->ah.key, &auth_sa->key, sizeof(ipsec_key_t));
	}

	if (tun) {
		entry->tun_src_ip = tun->tun_src_ip;
		entry->tun_dst_ip = tun->tun_dst_ip;
		mode = IPSEC_SA_MODE_TUNNEL;

		int ret;

		if (!in) {
			/* init tun hdr id */
			ret = odp_random_data((uint8_t *)
					      &entry->state.tun_hdr_id,
					      sizeof(entry->state.tun_hdr_id),
					      1);
			if (ret != sizeof(entry->state.tun_hdr_id))
				return -1;
		}
	}
	entry->mode = mode;

	/* Initialize state */
	entry->state.esp_seq = 0;
	entry->state.ah_seq = 0;
	entry->state.session = session;

	/* Add entry to the appropriate list */
	ipsec_cache->index++;
	if (in) {
		entry->next = ipsec_cache->in_list;
		ipsec_cache->in_list = entry;
	} else {
		entry->next = ipsec_cache->out_list;
		ipsec_cache->out_list = entry;
	}

	return 0;
}