A SERVICE OF

logo

Chapter 5 Non-Cryptographic Operations 157
Message Digests
B_DigestUpdate before calling B_DigestFinal(). This is useful when an application
is called upon to digest large amounts of data. It will feed "bite-sized" pieces of data to
the algorithm object instead of having to fit the entire input data into memory at one
time. The
DigestDataMultipleUpdates helper function in mdigsv.c shows this
scenario. Another possibility, if an application needs to be able to save and restore an
algorithm object, is to take advantage of
B_GetAlgorithmState and
B_SetAlgorithmState. Remember that a B_ALGORITHM_OBJ is an opaque pointer to
buffers controlled by the Crypto-C library; you cannot just save a
B_ALGORITHM_OBJ
value to a file and expect to use it later.
In
mdigsv.c, we demonstrate the serialization of an algorithm object by digesting a
file 100 bytes at a time, saving and restoring the algorithm object before each call to
B_DigestUpdate. Note that we begin by obtaining the initial state of the digest
algorithm object after calling
B_DigestInit.
Since the buffer in initialState belongs to Crypto-C, we need to make our own local
copy, since subsequent calls to Crypto-C can change the data pointed to by
initialState.
The
DigestDataSavedState() function takes in the given state info in order to restore
the algorithm object and continue with a call to
B_DigestUpdate. We make a call to
this helper function for each block of data that we read from the file. Note that
stateInfo is both an input and output argument; on input, it contains the algorithm
object state that will be used to restore the object and is later updated to contain the
ITEM initialState = {NULL, 0};
if ((status = B_GetAlgorithmState (&initialState, digestObj)) != 0)
break;
ITEM stateInfo = {NULL, 0};
stateInfo.len = initialState.len;
stateInfo.data = T_malloc (stateInfo.len);
if (stateInfo.data == NULL) {
status = RSA_DEMO_E_ALLOC;
break;
}
T_memcpy (stateInfo.data, initialState.data, stateInfo.len);