26 #include <arpa/inet.h>
43 #define SLEEP_IN_NANOS (10 * 1000)
44 #define DEFAULT_TIMEOUT (10)
45 #define SHA_ALGORITHM (DOCA_SHA_ALGORITHM_SHA256)
46 #define LOG_NUM_SHA_TASKS (0)
90 char *dst_buffer =
NULL;
91 uint32_t min_dst_sha_buffer_size;
96 &min_dst_sha_buffer_size);
98 DOCA_LOG_ERR(
"Failed to get minimum destination buffer size for DOCA SHA: %s",
103 dst_buffer = calloc(1, min_dst_sha_buffer_size);
104 if (dst_buffer ==
NULL) {
131 min_dst_sha_buffer_size,
134 DOCA_LOG_ERR(
"Unable to acquire DOCA buffer representing destination buffer: %s",
152 struct doca_sha *sha_ctx,
153 struct doca_buf **dst_doca_buf,
157 struct doca_buf *src_doca_buf;
158 struct doca_sha_task_hash *sha_hash_task =
NULL;
159 struct doca_task *task =
NULL;
160 size_t num_remaining_tasks = 0;
164 struct timespec ts = {
172 munmap(file_data, file_size);
178 munmap(file_data, file_size);
184 munmap(file_data, file_size);
191 DOCA_LOG_ERR(
"Unable to acquire DOCA buffer representing source buffer: %s",
198 DOCA_LOG_ERR(
"doca_buf_set_data() for request doca_buf failure");
210 ctx_user_data.
ptr = &num_remaining_tasks;
224 task_user_data.
ptr = &task_result;
241 num_remaining_tasks++;
251 while (num_remaining_tasks > 0) {
286 uint32_t min_partial_block_size)
291 uint32_t max_comch_msg;
293 uint32_t i, partial_block_size;
295 struct timespec ts = {
301 if (meta_msg ==
NULL) {
302 DOCA_LOG_ERR(
"Failed allocate memory for file metadata message");
307 if (max_comch_msg == 0 || min_partial_block_size > max_comch_msg) {
308 DOCA_LOG_ERR(
"Comch message size too small for minimum SHA block. Comch size: %u, partial SHA min: %u",
310 min_partial_block_size);
319 partial_block_size = max_comch_msg - (max_comch_msg % min_partial_block_size);
326 total_msgs = 1 + ((file_size - 1) / partial_block_size);
329 memcpy(&meta_msg->
sha_data[0], file_sha, sha_len);
342 for (i = 0; i < total_msgs; i++) {
343 msg_len =
MIN(file_size, partial_block_size);
362 file_data += msg_len;
363 file_size -= msg_len;
369 uint8_t *recv_buffer,
371 struct doca_comch_connection *comch_connection)
379 recv_buffer[msg_len] =
'\0';
387 struct doca_sha *sha_ctx)
389 struct doca_buf *dst_doca_buf;
390 struct timespec ts = {
393 char *file_data, *sha_output;
395 size_t hash_length, i;
398 uint64_t max_source_buffer_size;
399 uint32_t min_partial_block_size;
402 fd = open(
app_cfg->file_path, O_RDWR);
408 if (fstat(fd, &statbuf) < 0) {
417 &min_partial_block_size);
419 DOCA_LOG_ERR(
"Failed to get the partial hash block size for DOCA SHA: %s",
432 if (statbuf.st_size <= 0 || (uint64_t)statbuf.st_size > max_source_buffer_size) {
433 DOCA_LOG_ERR(
"Invalid file size. Should be greater then zero and smaller than %lu",
434 max_source_buffer_size);
439 file_data =
mmap(
NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
440 if (file_data == MAP_FAILED) {
441 DOCA_LOG_ERR(
"Unable to map file content: %s", strerror(errno));
469 sha_output = calloc(1, (hash_length * 2) + 1);
470 if (sha_output ==
NULL) {
477 for (i = 0; i < hash_length; i++)
478 snprintf(sha_output + (2 * i), 3,
"%02x", sha_msg[i]);
509 uint8_t *recv_buffer,
511 struct doca_comch_connection *comch_connection)
516 struct doca_task *task;
518 struct timespec ts = {
533 server_data = &
cfg->server_data;
540 DOCA_LOG_ERR(
"Unexpected file metadata message received. Size %u, min expected size %lu",
558 memcpy(server_data->
sha_src_data, recv_buffer, msg_len);
584 DOCA_LOG_ERR(
"Failed to set source for SHA partial hash task: %s",
594 DOCA_LOG_ERR(
"Failed to set final buffer for SHA partial hash task: %s",
604 task_user_data.
ptr = &task_result;
629 if ((
size_t)write(server_data->
fd, recv_buffer, msg_len) != msg_len) {
630 DOCA_LOG_ERR(
"Failed to write the received message into the input file");
658 struct doca_buf *dst_doca_buf,
659 uint32_t max_comch_msg,
664 uint32_t received_sha_msg_size;
670 &received_sha_msg_size);
672 DOCA_LOG_ERR(
"Failed to get minimum destination buffer size for DOCA SHA: %s",
678 server_data->
expected_sha = calloc(1, received_sha_msg_size);
680 DOCA_LOG_ERR(
"Failed to allocate memory for received sha");
687 DOCA_LOG_ERR(
"Failed to allocate memory for SHA data buffer");
689 goto free_expected_sha;
696 goto free_sha_src_buf;
702 goto free_sha_src_buf;
712 DOCA_LOG_ERR(
"Unable to acquire DOCA buffer representing source buffer: %s",
758 server_data->
fd = fd;
802 struct doca_sha *sha_ctx)
804 struct doca_buf *dst_doca_buf =
NULL;
805 uint32_t i, max_comch_msg;
810 char finish_msg[] =
"Server was done receiving messages";
813 struct timespec ts = {
822 fd = open(
app_cfg->file_path, O_CREAT | O_WRONLY, S_IRUSR | S_IRGRP);
849 if (counter == num_of_iterations) {
850 DOCA_LOG_ERR(
"Message was not received at the given timeout");
869 if (hash_length == 0) {
870 DOCA_LOG_ERR(
"Error in calculating SHA - output length is 0");
882 sha_output = calloc(1, (hash_length * 2) + 1);
883 if (sha_output ==
NULL) {
884 DOCA_LOG_ERR(
"Failed to allocate memory to display SHA");
889 for (i = 0; i < hash_length; i++)
890 snprintf(sha_output + (2 * i), 3,
"%02x", file_sha[i]);
895 if (memcmp(file_sha,
app_cfg->server_data.expected_sha, hash_length) == 0)
896 DOCA_LOG_INFO(
"SUCCESS: file SHA is identical to received SHA");
898 DOCA_LOG_ERR(
"ERROR: SHA is not identical, file was compromised");
899 if (remove(
app_cfg->file_path) < 0)
927 size_t *num_remaining_tasks = (
size_t *)ctx_user_data.
ptr;
933 --*num_remaining_tasks;
949 size_t *num_remaining_tasks = (
size_t *)ctx_user_data.
ptr;
954 --*num_remaining_tasks;
970 size_t *num_remaining_tasks = (
size_t *)ctx_user_data.
ptr;
973 (void)sha_partial_hash_task;
976 --*num_remaining_tasks;
992 size_t *num_remaining_tasks = (
size_t *)ctx_user_data.
ptr;
997 --*num_remaining_tasks;
1015 struct doca_sha **sha_ctx)
1017 uint32_t max_bufs = 2;
1035 goto destroy_core_objs;
1080 DOCA_LOG_ERR(
"Failed to set configuration for SHA partial hash task: %s",
1108 if (sha_ctx !=
NULL) {
1149 char *dev_pci_addr = (
char *)param;
1152 DOCA_LOG_ERR(
"Entered device PCI address exceeding the maximum size of %d",
1170 const char *rep_pci_addr = (
char *)param;
1174 DOCA_LOG_ERR(
"Entered device representor PCI address exceeding the maximum size of %d",
1198 DOCA_LOG_ERR(
"Timeout parameter must be positive value");
1229 struct doca_argp_param *dev_pci_addr_param, *rep_pci_addr_param, *file_param, *timeout_param;
1293 "Application timeout for receiving file content messages, default is 5 sec");
void * comch_utils_get_user_data(struct doca_comch_connection *connection)
doca_error_t comch_utils_progress_connection(struct doca_comch_connection *connection)
struct doca_comch_connection * comch_util_get_connection(struct comch_cfg *comch_cfg)
doca_error_t comch_utils_send(struct doca_comch_connection *connection, const void *msg, uint32_t len)
uint32_t comch_utils_get_max_buffer_size(struct comch_cfg *comch_cfg)
doca_error_t request_stop_ctx(struct doca_pe *pe, struct doca_ctx *ctx)
doca_error_t destroy_core_objects(struct program_core_objects *state)
doca_error_t create_core_objects(struct program_core_objects *state, uint32_t max_bufs)
doca_error_t open_doca_device_with_capabilities(tasks_check func, struct doca_dev **retval)
DOCA_LOG_REGISTER(FILE_INTEGRITY::Core)
doca_error_t register_file_integrity_params(void)
static void uninit_async_sha_recv_data(struct server_runtime_data *server_data)
doca_error_t file_integrity_server(struct comch_cfg *comch_cfg, struct file_integrity_config *app_cfg, struct program_core_objects *state, struct doca_sha *sha_ctx)
static doca_error_t send_file(struct comch_cfg *comch_cfg, struct file_integrity_config *app_cfg, char *file_data, size_t file_size, uint8_t *file_sha, size_t sha_len, uint32_t min_partial_block_size)
void file_integrity_cleanup(struct program_core_objects *state, struct doca_sha *sha_ctx)
static void free_cb(void *addr, size_t len, void *opaque)
static doca_error_t calculate_sha(struct program_core_objects *state, struct doca_sha *sha_ctx, struct doca_buf **dst_doca_buf, char *file_data, size_t file_size)
static void sha_partial_hash_error_callback(struct doca_sha_task_partial_hash *sha_partial_hash_task, union doca_data task_user_data, union doca_data ctx_user_data)
static doca_error_t init_async_sha_recv_data(struct doca_sha *sha_ctx, struct program_core_objects *state, struct server_runtime_data *server_data, struct doca_buf *dst_doca_buf, uint32_t max_comch_msg, int fd)
static doca_error_t rep_pci_addr_callback(void *param, void *config)
static void sha_hash_completed_callback(struct doca_sha_task_hash *sha_hash_task, union doca_data task_user_data, union doca_data ctx_user_data)
doca_error_t file_integrity_init(struct file_integrity_config *app_cfg, struct program_core_objects *state, struct doca_sha **sha_ctx)
static void sha_partial_hash_completed_callback(struct doca_sha_task_partial_hash *sha_partial_hash_task, union doca_data task_user_data, union doca_data ctx_user_data)
doca_error_t file_integrity_client(struct comch_cfg *comch_cfg, struct file_integrity_config *app_cfg, struct program_core_objects *state, struct doca_sha *sha_ctx)
static doca_error_t timeout_callback(void *param, void *config)
#define LOG_NUM_SHA_TASKS
static doca_error_t sha_partial_hash_is_supported(struct doca_devinfo *devinfo)
void server_recv_event_cb(struct doca_comch_event_msg_recv *event, uint8_t *recv_buffer, uint32_t msg_len, struct doca_comch_connection *comch_connection)
void client_recv_event_cb(struct doca_comch_event_msg_recv *event, uint8_t *recv_buffer, uint32_t msg_len, struct doca_comch_connection *comch_connection)
static void unmap_cb(void *addr, size_t len, void *opaque)
static doca_error_t args_validation_callback(void *cfg)
static void sha_hash_error_callback(struct doca_sha_task_hash *sha_hash_task, union doca_data task_user_data, union doca_data ctx_user_data)
static doca_error_t dev_pci_addr_callback(void *param, void *config)
static doca_error_t populate_dst_buf(struct program_core_objects *state, struct doca_buf **dst_doca_buf)
static doca_error_t file_callback(void *param, void *config)
static struct app_gpu_cfg app_cfg
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_validation_callback(doca_argp_validation_cb_t callback)
Register program validation callback function.
DOCA_EXPERIMENTAL void doca_argp_param_set_description(struct doca_argp_param *param, const char *description)
Set the description of the program param, used during program usage.
DOCA_EXPERIMENTAL void doca_argp_param_set_long_name(struct doca_argp_param *param, const char *name)
Set the long name of the program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_callback(struct doca_argp_param *param, doca_argp_param_cb_t callback)
Set the callback function of the program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_mandatory(struct doca_argp_param *param)
Mark the program param as mandatory.
DOCA_EXPERIMENTAL doca_error_t doca_argp_param_create(struct doca_argp_param **param)
Create new program param.
DOCA_EXPERIMENTAL void doca_argp_param_set_type(struct doca_argp_param *param, enum doca_argp_type type)
Set the type of the param arguments.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_version_callback(doca_argp_param_cb_t callback)
Register an alternative version callback.
DOCA_EXPERIMENTAL void doca_argp_param_set_short_name(struct doca_argp_param *param, const char *name)
Set the short name of the program param.
DOCA_EXPERIMENTAL doca_error_t doca_argp_register_param(struct doca_argp_param *input_param)
Register a program flag.
static doca_error_t doca_buf_inventory_buf_get_by_addr(struct doca_buf_inventory *inventory, struct doca_mmap *mmap, void *addr, size_t len, struct doca_buf **buf)
Allocate single element from buffer inventory and point it to the buffer defined by addr & len argume...
static doca_error_t doca_buf_inventory_buf_get_by_data(struct doca_buf_inventory *inventory, struct doca_mmap *mmap, void *data, size_t data_len, struct doca_buf **buf)
Allocate single element from buffer inventory and point it to the buffer defined by data & data_len a...
DOCA_STABLE doca_error_t doca_buf_dec_refcount(struct doca_buf *buf, uint16_t *refcount)
Decrease the object reference count by 1, if 0 reached, return the element back to the inventory.
DOCA_STABLE doca_error_t doca_buf_get_data(const struct doca_buf *buf, void **data)
Get the buffer's data.
DOCA_STABLE doca_error_t doca_buf_get_data_len(const struct doca_buf *buf, size_t *data_len)
Get buffer's data length.
DOCA_STABLE doca_error_t doca_buf_set_data(struct doca_buf *buf, void *data, size_t data_len)
DOCA_STABLE doca_error_t doca_ctx_start(struct doca_ctx *ctx)
Finalizes all configurations, and starts the DOCA CTX.
DOCA_STABLE doca_error_t doca_ctx_set_user_data(struct doca_ctx *ctx, union doca_data user_data)
set user data to context
DOCA_STABLE doca_error_t doca_ctx_stop(struct doca_ctx *ctx)
Stops the context allowing reconfiguration.
#define DOCA_DEVINFO_REP_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
#define DOCA_DEVINFO_PCI_ADDR_SIZE
Buffer size to hold PCI BDF format: "XXXX:XX:XX.X". Including a null terminator.
DOCA_STABLE struct doca_devinfo * doca_dev_as_devinfo(const struct doca_dev *dev)
Get local device info from device. This should be useful when wanting to query information about devi...
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
DOCA_STABLE doca_error_t doca_mmap_set_memrange(struct doca_mmap *mmap, void *addr, size_t len)
Set the memory range of DOCA memory map.
DOCA_STABLE doca_error_t doca_mmap_start(struct doca_mmap *mmap)
Start DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_set_free_cb(struct doca_mmap *mmap, doca_mmap_memrange_free_cb_t *free_cb, void *opaque)
Set callback that will free the memory range when destroying DOCA memory map.
DOCA_STABLE doca_error_t doca_mmap_stop(struct doca_mmap *mmap)
Stop DOCA Memory Map.
DOCA_STABLE doca_error_t doca_task_get_status(const struct doca_task *task)
Get task status.
DOCA_STABLE doca_error_t doca_pe_connect_ctx(struct doca_pe *pe, struct doca_ctx *ctx)
This method connects a context to a progress engine.
DOCA_STABLE doca_error_t doca_task_submit(struct doca_task *task)
Submit a task to a progress engine.
DOCA_STABLE uint8_t doca_pe_progress(struct doca_pe *pe)
Run the progress engine.
DOCA_STABLE void doca_task_set_user_data(struct doca_task *task, union doca_data user_data)
Set user data to a task.
DOCA_STABLE void doca_task_free(struct doca_task *task)
Free a task back to where it was allocated from.
DOCA_EXPERIMENTAL doca_error_t doca_sha_cap_get_partial_hash_block_size(struct doca_devinfo const *devinfo, enum doca_sha_algorithm algorithm, uint32_t *partial_block_size)
DOCA_EXPERIMENTAL struct doca_task * doca_sha_task_partial_hash_as_task(struct doca_sha_task_partial_hash *task)
DOCA_EXPERIMENTAL doca_error_t doca_sha_create(struct doca_dev *dev, struct doca_sha **sha)
DOCA_EXPERIMENTAL doca_error_t doca_sha_cap_get_min_dst_buf_size(struct doca_devinfo const *devinfo, enum doca_sha_algorithm algorithm, uint32_t *min_dst_buf_size)
DOCA_EXPERIMENTAL struct doca_task * doca_sha_task_hash_as_task(struct doca_sha_task_hash *task)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_partial_hash_set_is_final_buf(struct doca_sha_task_partial_hash *task)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_partial_hash_alloc_init(struct doca_sha *sha, enum doca_sha_algorithm algorithm, struct doca_buf const *src_buf, struct doca_buf *dst_buf, union doca_data user_data, struct doca_sha_task_partial_hash **task)
DOCA_EXPERIMENTAL doca_error_t doca_sha_cap_task_partial_hash_get_supported(struct doca_devinfo const *devinfo, enum doca_sha_algorithm algorithm)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_partial_hash_set_conf(struct doca_sha *sha, doca_sha_task_partial_hash_completion_cb_t task_completion_cb, doca_sha_task_partial_hash_completion_cb_t task_error_cb, uint8_t log_num_tasks)
This method sets the doca_sha partial hash task pool configuration.
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_partial_hash_set_src(struct doca_sha_task_partial_hash *task, struct doca_buf const *src_buf)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_hash_set_conf(struct doca_sha *sha, doca_sha_task_hash_completion_cb_t task_completion_cb, doca_sha_task_hash_completion_cb_t task_error_cb, uint8_t log_num_tasks)
This method sets the doca_sha hash task pool configuration.
DOCA_EXPERIMENTAL doca_error_t doca_sha_destroy(struct doca_sha *sha)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_hash_alloc_init(struct doca_sha *sha, enum doca_sha_algorithm algorithm, struct doca_buf const *src_buf, struct doca_buf *dst_buf, union doca_data user_data, struct doca_sha_task_hash **task)
DOCA_EXPERIMENTAL doca_error_t doca_sha_task_hash_set_src(struct doca_sha_task_hash *task, struct doca_buf const *src_buf)
DOCA_EXPERIMENTAL doca_error_t doca_sha_cap_get_max_src_buf_size(struct doca_devinfo const *devinfo, uint64_t *max_src_buf_size)
DOCA_EXPERIMENTAL struct doca_ctx * doca_sha_as_ctx(struct doca_sha *sha)
const struct ip_frag_config * cfg
enum transfer_state state
char file_path[MAX_FILE_NAME]
struct doca_mmap * src_mmap
struct doca_buf_inventory * buf_inv
struct doca_mmap * dst_mmap
struct doca_sha_task_partial_hash * sha_partial_hash_task
uint32_t expected_sha_len
uint32_t received_file_length
uint32_t expected_file_chunks
uint32_t received_file_chunks
struct doca_buf * sha_src_buf
struct doca_sha_task_hash * sha_hash_task
struct program_core_objects * sha_state
Convenience type for representing opaque data.
size_t strlcpy(char *dst, const char *src, size_t size)
noreturn doca_error_t sdk_version_callback(void *param, void *doca_config)