caam-blob-example: fix the maximum input size to match the one in the driver

It was believed that the CAAM was able to create blobs from files of up to
1 MiB, because in some cases, encrypting and decrypting a large file would
result in a file identical to the original one. In reality, the CAAM's job
descriptors use 16 bits to store input/output sizes, so any size that takes up
more than 16 bits either causes the operation to fail or makes the CAAM
continue with the operation, but truncating the size to its 16 least
significant bits.

Encryption and decryption cycles that seem to work with large files are
actually encrypting and decrypting part of the original file and storing the
output in the memory address where the original file was stored, making it seem
like the process was successful when it really isn't. It's also possible that,
even if both operations work fine, the final decrypted file will differ from the
original one because it contains the decrypted truncated blob plus whatever
comes after it in memory.

Fix the size limit, dynamically alter it during runtime depending on the
operation and exit if the limit is surpassed to avoid including unrelated
memory contents in the output.

https://jira.digi.com/browse/DEL-7378

Signed-off-by: Gabriel Valcazar <gabriel.valcazar@digi.com>
This commit is contained in:
Gabriel Valcazar 2021-01-14 13:21:22 +01:00
parent f397c85183
commit 35b859e87a
3 changed files with 23 additions and 9 deletions

View File

@ -5,7 +5,7 @@ This example application shows how to encapsulate/decapsulate data to/from CAAM
CAAM blobs are a way to protect sensitive data by encrypting their contents.
You can think of CAAM blobs as data encrypted with an internal unreadable device-specific key which is protected by the hardware.
Data encapsulated in a CAAM blob can only be decapsulated by the device that created it.
When creating CAAM blobs, the input data size is limited to 1048527 bytes.
When creating CAAM blobs, the input data size is limited to 65487 bytes.
Note that CAAM blobs are slightly bigger than the input data (48 bytes bigger).
A key modifier may be used to further differentiate the key used in a particular blob.
@ -65,7 +65,7 @@ For more information, see the [Digi Embedded Yocto online documentation](https:/
License
-------
Copyright 2019, Digi International Inc.
Copyright 2019-2021, Digi International Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice

View File

@ -1,7 +1,7 @@
/*
* caam_ops.h
*
* Copyright (C) 2019 by Digi International Inc.
* Copyright (C) 2019-2021, by Digi International Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@ -32,10 +32,13 @@
/* Key modifier: 16 bytes for a general memory blob (see SRM 5.8.4.7.1) */
#define KEY_MODIFIER_SIZE 16
#define SZ_1K 1024
/*
* Testing shows that input sizes bigger than this value usually fail.
* The input size is stored in 16 bits in the CAAM job descriptor, which means
* the upper limit is 64 KiB minus one byte
*/
#define BLOB_MAX_INPUT_SIZE (1024 * 1024 - BLOB_OVERHEAD)
#define BLOB_MAX_INPUT_SIZE (64 * SZ_1K - 1)
int caamblob_encrypt(const uint8_t *data,
size_t size,

View File

@ -1,7 +1,7 @@
/*
* main.c
*
* Copyright (C) 2019 by Digi International Inc.
* Copyright (C) 2019-2021 by Digi International Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@ -168,6 +168,7 @@ int main(int argc, char *argv[])
size_t output_len;
uint8_t key_modifier[KEY_MODIFIER_SIZE];
int ret = EXIT_SUCCESS;
size_t max_input_len = BLOB_MAX_INPUT_SIZE;
if (argc > 0)
program_name = argv[0];
@ -187,10 +188,20 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
/*
* if we're going to encrypt a file, subtract the blob overhead from
* the maximum allowed size so that the output blob size can fit in the
* CAAM encryption job descriptor
*/
max_input_len -= op == ENCRYPT ? BLOB_OVERHEAD : 0;
/* this is a limitation of the current driver implementation */
if (input_len >= BLOB_MAX_INPUT_SIZE)
fprintf(stderr, "[WARNING] Input is too big, %s may fail\n",
op == ENCRYPT ? "encryption" : "decryption");
if (input_len > max_input_len) {
fprintf(stderr, "[ERROR] Input is too big, continuing may result in unexpected behavior.\n"
"[ERROR] The maximum input size for %s is %u bytes.\n",
op == ENCRYPT ? "encryption" : "decryption", max_input_len);
return EXIT_FAILURE;
}
input_data = mmap(NULL, input_len, PROT_READ,
MAP_PRIVATE | MAP_POPULATE, input_fd, 0);