DOCA SHA
This guide provides developer focused instructions on deploying and programming the DOCA SHA library.
The DOCA SHA library provides a flexible and unified API to leverage the SHA offload engine present in the NVIDIA® BlueField® DPU. For more information on SHA (secure hash standard algorithm), please review the FIPS 180-4 specifications.
SHA hardware acceleration engine is only available on the BlueField-2 DPU. Thus, the DOCA SHA library is not available for BlueField-3 DPUs.
SHA is commonly used in cryptography to generate a given hash value for a supplied input buffer. Depending on the SHA algorithm used, the message length may vary: Any length less than 264 bits for SHA-1, SHA-224, and SHA-256, or less than 2128 bits for SHA-384, SHA-512, SHA-512/224, and SHA-512/256. The resulting output from a SHA operation is called a message digest. The message digests range in length from 160 to 512 bits depending on the selected SHA algorithm. As expected from any cryptography algorithm, any change to a message will, with a very high probability, result in a different message digest and verification failure.
SHA is typically used with other cryptographic algorithms, such as digital signature algorithms and keyed-hash message authentication codes, or in the generation of random numbers.
The DOCA SHA library supports three SHA algorithms, SHA-1, SHA-256, and SHA-512, and aims to comply with the OpenSSL SHA implementation standard. It supports both one-shot and stateful SHA calculations.
One-shot means that the input message is composed of a single segment of data and, therefore, the SHA operation is completed in a single step (i.e., one single SHA engine enqueue and dequeue operation)
Stateful means that the input message is composed of many segments of data and, therefore, its SHA calculation needs more than one SHA enqueue and dequeue operation to finish. During any stateful operation, other SHA operations can also be executed.
DOCA SHA applications can run either on the host machine or directly on the crypto-enabled DPU target. As the DOCA SHA leverages the SHA engine, users must make sure it is enabled:
$ sudo mlxfwmanager
In the output, make sure that Crypto Enabled
appears in the command output in the Description
line.
The following diagram shows how the DOCA SHA library receives a message and outputs a message digest.
From an application level, the DOCA SHA library can be seen as a black box. DOCA SHA outputs a response regardless of the nature of the input message.

In a one-shot SHA situation, the single output is the correct message digest
In a stateful SHA situation, multiple outputs are expected corresponding to multiple inputs but only the last output is the correct message digest
In the following sections, additional details about the library API are provided. For more information, please refer to the NVIDIA DOCA Library APIs reference.
doca_sha_job_type
The enum defines six job types in the DOCA SHA library.
enum doca_sha_job_type {
DOCA_SHA_JOB_SHA1 = DOCA_ACTION_SHA_FIRST + 1,
DOCA_SHA_JOB_SHA256,
DOCA_SHA_JOB_SHA512,
DOCA_SHA_JOB_SHA1_PARTIAL,
DOCA_SHA_JOB_SHA256_PARTIAL,
DOCA_SHA_JOB_SHA512_PARTIAL,
};
DOCA_SHA_JOB_SHA1
;DOCA_SHA_JOB_SHA256
;DOCA_SHA_JOB_SHA512
– used to specify a one-shot SHA calculationDOCA_SHA_JOB_SHA1_PARTIAL
;DOCA_SHA_JOB_SHA256_PARTIAL
;DOCA_SHA_JOB_SHA512_PARTIAL
– used to specify a stateful SHA calculation
DOCA SHA Output Length Macro
These macros define the smallest SHA response buffer length corresponding to different job types.
#define DOCA_SHA1_BYTE_COUNT 20
#define DOCA_SHA256_BYTE_COUNT 32
#define DOCA_SHA512_BYTE_COUNT 64
DOCA_SHA1_BYTE_COUNT
– number of message digest bytes forSHA1_PARTIAL
andSHA1_PARTIAL
DOCA_SHA256_BYTE_COUNT
– number of message digest bytes forSHA256_PARTIAL
andSHA256_PARTIAL
DOCA_SHA512_BYTE_COUNT
– number of message digest bytes forSHA512_PARTIAL
andSHA512_PARTIAL
doca_sha_job_flags
The enum defines flags used for doca_sha_job
construction.
enum doca_sha_job_flags {
DOCA_SHA_JOB_FLAGS_NONE = 0,
DOCA_SHA_JOB_FLAGS_SHA_PARTIAL_FINAL
};
DOCA_SHA_JOB_FLAGS_NONE
– the default flag suitable for all SHA jobsDOCA_SHA_JOB_FLAGS_SHA_PARTIAL_FINAL
– signifies that the current input is the final segment of a whole stateful job
doca_sha_job
This is the DOCA SHA job definition, suitable for one-shot SHA job types, DOCA_ JOB_SHA1/256/512
.
struct doca_sha_job {
struct doca_job base;
struct doca_buf *req_buf;
struct doca_buf *resp_buf;
uint64_t flags;
};
base
– an opaquedoca_job
structurereq_buf
– thedoca_buf
containing the input messageresp_buf
– thedoca_buf
used for the output message digestflags
– thedoca_sha_job_flags
doca_sha_partial_session
An opaque structure used in a stateful SHA job.
struct doca_sha_partial_session;
doca_sha_partial_job
This is the DOCA SHA job definition, suitable for stateful SHA job types, DOCA_JOB_SHA1/256/512_PARTIAL
.
struct doca_sha_partial_job {
struct doca_sha_job sha_job;
struct doca_sha_partial_session *session;
};
sha_job
– contain the fields for the input message, output message digest, and flagssession
– contain the state information for a stateful SHA calculation
doca_sha
An opaque structure for DOCA SHA API.
struct doca_sha;
doca_sha_create
Before performing any SHA operation, it is essential to create a doca_sha
object.
doca_error_t doca_sha_create(struct doca_sha **ctx);
ctx [in/out]
–doca_sha
object to be createdReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_destroy
Used to destroy a doca_sha object after a SHA operation is done:
doca_error_t doca_sha_destroy(struct doca_sha *ctx);
ctx [in]
–doca_sha
object to be destroyed; it is created bydoca_sha_create()
Returns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_job_get_supported
Check whether a device can perform doca_sha
jobs.
doca_error_t doca_sha_destroy(struct doca_sha *ctx);
devinfo [in]
– a pointer to thedoca_devinfo
objectjob_type [in]
–d
oca_sha
job type enumReturns –
D
OCA_SUCCESS
on success, error code otherwise
doca_sha_get_max_list_buf_num_elem
Get the maximum linked_list doca_buf count for the source buffer in a doca_sha job.
doca_error_t doca_sha_get_max_list_buf_num_elem(const struct doca_devinfo *devinfo, uint32_t *max_list_num_elem);
devinfo [in]
– a pointer to the doca_devinfo objectmax_list_num_elem [out]
– maximum linked listdoca_buf
countReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_get_max_src_buffer_size
Get the maximum buffer byte count for the source buffer in a doca_sha job.
doca_error_t doca_sha_get_max_src_buffer_size(const struct doca_devinfo *devinfo, uint64_t *max_buffer_size);
devinfo [in]
– a pointer to thedoca_devinfo
objectmax_buffer_size [out]
– maximum buffer byte countReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_get_min_dst_buffer_size
Get the minimum buffer byte count for the destination buffer in a doca_sha job.
doca_error_t doca_sha_get_max_src_buffer_size(const struct doca_devinfo *devinfo, uint64_t *max_buffer_size);
devinfo [in]
– A pointer to thedoca_devinfo
objectjob_type [in]
–doca_sha
job type enummin_buffer_size [out]
– Minimum buffer byte countReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_get_hardware_supported
Check that a doca_sha
engine is supported.
doca_error_t doca_sha_get_hardware_supported(const struct doca_devinfo *devinfo);
devinfo [in]
– a pointer to thedoca_devinfo
objectReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_as_ctx
Convert a doca_sha object into a doca object:
struct doca_ctx *doca_sha_as_ctx(struct doca_sha *ctx);
ctx [in]
– a pointer to thedoca_sha
objectdoca_ctx [out]
– a pointer to thedoca
objectReturns – a pointer to the
doca
object on success,NULL
otherwise
doca_sha_partial_session_create
Before doing any stateful SHA calculation, it is necessary to create a doca_sha_partial_session object to keep the state information:
doca_error_t doca_sha_partial_session_create(
struct doca_sha *ctx,
struct doca_workq *workq,
struct doca_sha_partial_session **session);
ctx [in]
– a pointer to thedoca_sha
objectworkq [in]
– a pointer to thedoca_workq
objectsession [in/out]
– a pointer to thedoca_sha_partial_session
object to be createdReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_partial_session_destroy
Free stateful SHA session resource:
doca_error_t doca_sha_partial_session_destroy(
struct doca_sha *ctx,
struct doca_workq *workq,
struct doca_sha_partial_session *session);
ctx [in]
– a pointer to thedoca_sha
objectworkq [in]
– a pointer to thedoca_workq
objectsession [in]
– a pointer to thedoca_sha_partial_session
object to be freedReturns –
DOCA_SUCCESS
on success, error code otherwise
doca_sha_partial_session_copy
Copy the stateful SHA session resource:
doca_error_t doca_sha_partial_session_copy(
struct doca_sha *ctx,
struct doca_workq *workq,
struct doca_sha_partial_session *from,
struct doca_sha_partial_session *to);
ctx [in]
– a pointer to thedoca_sha
objectworkq [in]
– a pointer to thedoca_workq
objectfrom [in]
– a pointer to the sourcedoca_sha_partial_session
object to be copiedto [out]
– a pointer to the destinationdoca_sha_partial_session
objectReturns –
DOCA_SUCCESS
on success, error code otherwise
Capabilities and Limitations
Supported SHA algorithms:
SHA1
SHA256
SHA512
Output message digest length:
20B for SHA1
32B for SHA256
64B for SHA512
Maximum single job size:
For one-shot SHA calculation, the input message size must be ≤ 231
For stateful SHA calculation, the accumulated input message size must be ≤ 231
Stateful SHA job length requirement:
For
SHA1/256_PARTIAL
, only the last segment allows itsbyte_count
!= multiple-of-64For
SHA512_PARTIAL
, only the last segment allows itsbyte_count
!= multiple-of-128
Performing One-shot SHA Calculation
Construct a
doca_sha_job
:struct doca_sha_job job = { .base.type = DOCA_SHA_JOB_SHA1, .req_buf = user_req_buf, .resp_buf = user_resp_buf, .flags = DOCA_SHA_JOB_FLAGS_NONE };
Submit the job until
DOCA_SUCCESS
is received:In synchronous mode, we can use: ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit;
If
doca_workq_submit()
returnsDOCA_ERROR_INVALID_VALUE
, it means the job construction has a problem. If it returnsDOCA_ERROR_BAD_STATE
, it indicates a fatal internal error and the whole engine must be reinitialized.In asynchronous mode,
doca_workq_submit()
may returnDOCA_ERROR_NO_MEMORY
. In that case, you must first calldoca_workq_progress_retrieve()
to receive a response so that the job resource can be freed, then retry callingdoca_workq_submit()
.Possible
doca_workq_submit()
return codes:DOCA_SUCCESS
DOCA_ERROR_INVALID_VALUE
DOCA_ERROR_NO_MEMORY
DOCA_ERROR_BAD_STATE
To retrieve a job response until
DOCA_SUCCESS
is received:while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
If
doca_workq_progress_retrieve()
returnsDOCA_ERROR_INVALID_VALUE
it means invalid input is received. If it returnsDOCA_ERROR_IO_FAILED
, it signifies fatal internal error and the whole engine needs reinitialized.Possible
doca_workq_progress_retrieve()
return codes:DOCA_SUCCESS
DOCA_ERROR_INVALID_VALUE
DOCA_ERROR_NO_MEMORY
DOCA_ERROR_BAD_STATE
Performing Stateful SHA Calculation
This section describes the steps to finish a stateful SHA1 calculation, assuming the whole job is composed of three or more segments.
Obtain a
doca_sha_partial_session
:doca_sha_partial_session *session; doca_sha_partial_session_create(ctx, workq, &session);
Construct a
doca_sha_partial_job
for the first segment:struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_1st_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_NONE, .session = session, };
Submit the job for the first segment:
ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit;
Wait until first segment processing is done:
while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
The purpose of this call is to make sure the first segment processing is finished before continuing to send the next segment, as it is necessary to sequentially process all segments for a correct message digest generation. The
user_resp_buf
at this moment contains garbage values.For the second segment, repeat the previous three steps:
struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_2nd_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_NONE, .session = session, }; ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit; while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
The purpose of this call is still to make sure the second segment processing is finished. The user
user_resp_buf
at this moment still contains garbage values.All subsequent segments repeat the same process.
For the last segment, repeat the same process while setting the special flag for the last segment:
struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_the_last_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_SHA_PARTIAL_LAST, .session = session, }; ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit; while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
After the
DOCA_SUCCESS
event of the last segment is received the processing of the whole job is done now. You can get the expected SHA message digest from theuser_resp_buf
now.Release the session object:
doca_sha_partial_session_destroy(ctx, workq, session);
Notes:
Before submitting the first segment, call
doca_sha_partial_session_create()
to obtain a "session" object.During the whole process, make sure to use the same
doca_sha_partial_session
object used for all segments of the entire job.If a session object is released before the whole stateful SHA is finished, or if different objects are used for a stateful SHA, the job submission may fail due to job validity check failure. Even the job submission succeeds, a wrong SHA message digest is expected.
The session resource is limited, it is the user's responsibility to properly call
doca_sha_partial_session_destroy()
to make sure all allocated session objects are released.For the last segment, the
DOCA_SHA_JOB_FLAGS_SHA_PARTIAL_FINAL
flag must be set.If
DOCA_SHA_JOB_FLAGS_SHA_PARTIAL_FINAL
is not properly set, the engine assumes an intermediate partial SHA calculation and returns an invalid SHA message digest. As only the user knows when the last segment arrives, it is their responsibility to properly set this flag.Make sure the
SHA_PARTIAL
segment length requirements are In this example, the first and second segments' byte count must be a multiple of 64. Otherwise, the job submission may fail due to job validity check failure.
Using Session Copy
This section describes the steps for utilizing session_copy()
to reduce the stateful SHA calculation overhead.
The example assumes there are two whole jobs, job_0
and job_1
, where job_0
is composed of several segments, {header_segment, job_0's other segments}
, and job_1
is composed of {header_segment, job_1' other segments}
.
Obtain two
doca_sha_partial_session
:doca_sha_partial_session *session_0; doca_sha_partial_session_create(ctx, workq, &session_0); doca_sha_partial_session *session_1; doca_sha_partial_session_create(ctx, workq, &session_1);
Construct a
doca_sha_partial_job
for theheader_segment
:struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_header_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_NONE, .session = session_0, };
Submit the
header_segment
ofjob_0
.ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit;
Wait until the processing of
header_segment
is done:while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
Perform the session copy so that
job_1
does not need to calculate itsheader_segment
:doca_sha_partial_session_copy(ctx, workq, session_0, session_1);
Continue to calculate
job_0
andjob_1
's other segments until final segment using normalpartial_sha
calculation process.struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_job_0_other_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_NONE, .session = session_0, }; ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit; while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit; struct doca_sha_partial_job job = { .sha_job.base.type = DOCA_SHA_JOB_SHA1_PARTIAL, .sha_job.req_buf = user_req_buf_of_job_1_other_segment, .sha_job.resp_buf = user_resp_buf, .sha_job.flags = DOCA_SHA_JOB_FLAGS_NONE, .session = session_1, }; ret = doca_workq_submit(workq, &job.base); if (ret != DOCA_SUCCESS) error_exit; while ((ret = doca_workq_progress_retrieve(workq, &event, DOCA_WORKQ_RETRIEVE_FLAGS_NONE)) == DOCA_ERROR_AGAIN); if (ret != DOCA_SUCCESS) error_exit;
Release the session object:
doca_sha_partial_session_destroy(ctx, workq, session_0); doca_sha_partial_session_destroy(ctx, workq, session_1);
This section provides instructions on how to test the DOCA SHA library:
Enable DOCA SHA test apps and build.
user@machine:/home/user$ cd ${YOUR-PATH}/doca user@machine:/home/user$ meson setup build user@machine:/home/user$ cd build user@machine:/home/user/doca/build$ meson configure -Dunit_test_lib_sha=true user@machine:/home/user/doca/build$ ninja
Run the test app
test_doca_sha_lite
. This test app shows how to do the simplest one-shot SHA calculation. It sends three messages and receives three massage digests for all SHA1, SHA256, and SHA512.user@machine:/home/user$ cd libs/doca_sha/src/unit_test/ user@machine:/home/user$ ./test_doca_sha_lite --pci_addr 03:00.0
Run the test app
test_doca_sha_benchmark
. This test app can be used to test throughput and more complex one-shot SHA calculation cases.Case 1: Test throughput of SHA1 with a 4096-byte input message.
user@machine:/home/user$ ./test_doca_sha_benchmark --pci_addr af:00.0 --data_file test_files/sha-input-4kbyte.txt --nb_iteration 1000000 --sha_type 0
Case 2: Test throughput of SHA256 with an 8192-byte input message.
user@machine:/home/user$ ./test_doca_sha_benchmark --pci_addr af:00.0 --data_file test_files/sha-input-8kbyte.txt --nb_iteration 1000000 --sha_type 1
Case 3: Calculate a SHA512 message digest with a random 16-byte input message.
user@machine:/home/user$ ./test_doca_sha_benchmark --pci_addr af:00.0 --nb_iteratoin 1 --use_random_data --data_byte_count 16 --sha_type 2
Case 4: Calculate a SHA1 message digest with a 1-gigabyte (230) input message.
user@machine:/home/user$ ./test_doca_sha_benchmark --pci_addr af:00.0 --data_file test_files/sha-input-1Gbyte.txt --nb_iteration 1 --sha_type 0
Run the test app
test_doca_sha_partial
. This test app can be used to show how to perform a stateful SHA calculation and thesession_copy
function.Case 1: Calculate a SHA1 message digest of two 129-byte messages. Each message is composed of three segments, the first and second segments are 64 bytes, the third segment is 1 byte.
user@machine:/home/user$ ./test_doca_sha_partial --pci_addr af:00.0 --job_byte_count 129 --segment_byte_count 64 --job_count 2 --mode 0 --sha_type 0
Case 2: Calculate a SHA256 message digest of a 2-gigabyte (231) message. This message is composed of 16 segments, each segment is 128 megabytes (227).
user@machine:/home/user$ ./test_doca_sha_partial --pci_addr af:00.0 --job_byte_count 134217728 --segment_byte_count 134217728 --job_count 1 --mode 3 --nb_sha_partial 16 --sha_type 1
Case 3: Calculate four SHA512 message digests of using the
session_copy
function. All the four jobs share the same job length, 129 bytes, and the same head segment, 128 bytes.user@machine:/home/user$ ./test_doca_sha_partial --pci_addr af:00.0 --job_byte_count 129 --segment_byte_count 128 --job_count 4 --mode 4 --sha_type 2
This section describes SHA samples based on the DOCA SHA library. These samples illustrate how to use the DOCA SHA API to calculate secure hash algorithm on a given message.
Running the Sample
Refer to the following documents:
NVIDIA DOCA Installation Guide for Linux for details on how to install BlueField-related software.
NVIDIA DOCA Troubleshooting Guide for any issue you may encounter with the installation, compilation, or execution of DOCA samples.
To build a given sample:
cd /opt/mellanox/doca/samples/doca_sha/<sample_name> meson /tmp/build ninja -C /tmp/build
NoteThe binary
doca_<sample_name>
will be created under/tmp/build/
.Sample (e.g., doca_sha_create) usage:
Usage: doca_sha_create [DOCA Flags] [Program Flags] DOCA Flags: -h, --help Print a help synopsis -v, --version Print program version information -l, --log-level Set the (numeric) log level
for
the program <10
=DISABLE,20
=CRITICAL,30
=ERROR,40
=WARNING,50
=INFO,60
=DEBUG,70
=TRACE> --sdk-log-level Set the SDK (numeric) log levelfor
the program <10
=DISABLE,20
=CRITICAL,30
=ERROR,40
=WARNING,50
=INFO,60
=DEBUG,70
=TRACE> -j, --json <path> Parse all command flags from an input json file Program Flags: -d, --data user dataFor additional information per sample, use the
-h
option:/tmp/build/doca_<sample_name> -h
Samples
SHA Create
This sample illustrates how to send A SHA job and retrieve the result.
The sample logic includes:
Locating a DOCA device.
Initializing the required DOCA core structures.
Populating DOCA memory map with two relevant buffers; one for the source data and one for the result.
Allocating the element in DOCA buffer inventory for each buffer.
Initializing a DOCA SHA job object.
Submitting the SHA job into work queue.
Retrieving the SHA job from the queue once it is done.
Printing the job result.
Destroying all SHA and DOCA core structures.
References:
/opt/mellanox/doca/samples/doca_sha/sha_create/sha_create_sample.c
/opt/mellanox/doca/samples/doca_sha/sha_create/sha_create_main.c
/opt/mellanox/doca/samples/doca_sha/sha_create/meson.build
SHA Partial Create
This sample illustrates how to send partial SHA jobs and retrieve the result. Each job source buffer (except the final) will be 64 bytes.
The sample logic includes:
Locating a DOCA device.
Initializing the required DOCA core structures.
Initializing a partial session for all the jobs.
Populating DOCA memory map with two relevant buffers; one for the source data and one for the result.
Allocating the element in DOCA buffer inventory for the result buffer.
Calculating total jobs; user data length divided by 64.
For each job:
Allocating the element in DOCA buffer inventory for the relevant part in the source buffer.
Initializing the DOCA SHA job object. If it is the final job, send
DOCA_SHA_JOB_FLAGS_SHA_PARTIAL_FINAL
flag.Submitting SHA job into work queue.
Retrieving SHA job from the queue once it is done.
Printing the final job result.
Destroying all SHA and DOCA core structures.
References:
/opt/mellanox/doca/samples/doca_sha/sha_partial_create/sha_partial_create_sample.c
/opt/mellanox/doca/samples/doca_sha/sha_partial_create/sha_partial_create_main.c
/opt/mellanox/doca/samples/doca_sha/sha_partial_create/meson.build