Skip to content

allow hash or mac on large buffers with less memory use #9758

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#define mbedtls_free free
#endif

// ---------------------------------- Macros -----------------------------------
#if !defined(MIN)
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif

// -------------------------------- Structures ---------------------------------
typedef struct psa_spm_hash_clone_s {
int32_t partition_id;
Expand All @@ -28,6 +33,12 @@ typedef struct psa_spm_hash_clone_s {
// ---------------------------------- Globals ----------------------------------
static int psa_spm_init_refence_counter = 0;

/* maximal memory allocation for reading large hash or mac input buffers.
the data will be read in chunks of size */
#if !defined (MAX_DATA_CHUNK_SIZE_IN_BYTES)
#define MAX_DATA_CHUNK_SIZE_IN_BYTES 400
#endif

#ifndef MAX_CONCURRENT_HASH_CLONES
#define MAX_CONCURRENT_HASH_CLONES 2
#endif
Expand Down Expand Up @@ -216,24 +227,40 @@ static void psa_mac_operation(void)
}

case PSA_MAC_UPDATE: {
uint8_t *input_ptr = mbedtls_calloc(1, msg.in_size[1]);
if (input_ptr == NULL) {

uint8_t *input_buffer = NULL;
size_t data_remaining = msg.in_size[1];
size_t allocation_size = MIN(data_remaining, MAX_DATA_CHUNK_SIZE_IN_BYTES);
size_t size_to_read = 0;

input_buffer = mbedtls_calloc(1, allocation_size);
if (input_buffer == NULL) {
status = PSA_ERROR_INSUFFICIENT_MEMORY;
break;
}

bytes_read = psa_read(msg.handle, 1, input_ptr,
msg.in_size[1]);
while (data_remaining > 0) {
size_to_read = MIN(data_remaining, MAX_DATA_CHUNK_SIZE_IN_BYTES);
bytes_read = psa_read(msg.handle, 1, input_buffer,
size_to_read);

if (bytes_read != msg.in_size[1]) {
SPM_PANIC("SPM read length mismatch");
if (bytes_read != size_to_read) {
SPM_PANIC("SPM read length mismatch");
}

status = psa_mac_update(msg.rhandle,
input_buffer,
bytes_read);

// stop on error
if (status != PSA_SUCCESS) {
break;
}
data_remaining = data_remaining - bytes_read;
}

status = psa_mac_update(msg.rhandle,
input_ptr,
msg.in_size[1]);
mbedtls_free(input_buffer);

mbedtls_free(input_ptr);
break;
}

Expand Down Expand Up @@ -363,23 +390,39 @@ static void psa_hash_operation(void)
}

case PSA_HASH_UPDATE: {
uint8_t *input_ptr = mbedtls_calloc(1, msg.in_size[1]);
if (input_ptr == NULL) {
uint8_t *input_buffer = NULL;
size_t data_remaining = msg.in_size[1];
size_t size_to_read = 0;
size_t allocation_size = MIN(data_remaining, MAX_DATA_CHUNK_SIZE_IN_BYTES);

input_buffer = mbedtls_calloc(1, allocation_size);
if (input_buffer == NULL) {
status = PSA_ERROR_INSUFFICIENT_MEMORY;
break;
}

bytes_read = psa_read(msg.handle, 1, input_ptr,
msg.in_size[1]);
while (data_remaining > 0) {
size_to_read = MIN(data_remaining, MAX_DATA_CHUNK_SIZE_IN_BYTES);
bytes_read = psa_read(msg.handle, 1, input_buffer,
size_to_read);

if (bytes_read != msg.in_size[1]) {
SPM_PANIC("SPM read length mismatch");
if (bytes_read != size_to_read) {
SPM_PANIC("SPM read length mismatch");
}

status = psa_hash_update(msg.rhandle,
input_buffer,
bytes_read);

// stop on error
if (status != PSA_SUCCESS) {
break;
}
data_remaining = data_remaining - bytes_read;
}

status = psa_hash_update(msg.rhandle,
input_ptr,
msg.in_size[1]);
mbedtls_free(input_ptr);
mbedtls_free(input_buffer);

break;
}

Expand Down