/* 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); }
/* 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); }
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(¶ms, &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; }