PS: Use buffer overlap for object encrypt/decrypt
Use the same buffer for plaintext and ciphertext in
psa_aead_encrypt/decrypt which is called in object
encryption and decryption.
Section "Overlap between parameters" of PSA Certified
Crypto API provides theory support for this.
Signed-off-by: Sherry Zhang <sherry.zhang2@arm.com>
Change-Id: I408032ccc5f48ccbb9c6fd6d56580bcc9456305e
diff --git a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.h b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.h
index a4dfd5b..e91e1bd 100644
--- a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.h
+++ b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.h
@@ -28,9 +28,9 @@
union ps_crypto_t {
struct {
uint8_t tag[PS_TAG_LEN_BYTES]; /*!< MAC value of AEAD object */
- uint8_t iv[PS_IV_LEN_BYTES]; /*!< IV value of AEAD object */
psa_storage_uid_t uid; /*!< UID for key label */
int32_t client_id; /*!< Owner client ID for key label */
+ uint8_t iv[PS_IV_LEN_BYTES]; /*!< IV value of AEAD object */
} ref;
};
diff --git a/secure_fw/partitions/protected_storage/ps_encrypted_object.c b/secure_fw/partitions/protected_storage/ps_encrypted_object.c
index 1f9068f..c622211 100644
--- a/secure_fw/partitions/protected_storage/ps_encrypted_object.c
+++ b/secure_fw/partitions/protected_storage/ps_encrypted_object.c
@@ -32,21 +32,13 @@
PS_TAG_LEN_BYTES : PS_IV_LEN_BYTES)
#define PS_CRYPTO_BUF_LEN (PS_MAX_ENCRYPTED_OBJ_SIZE + PS_TAG_IV_LEN_MAX)
-static uint8_t ps_crypto_buf[PS_CRYPTO_BUF_LEN];
-
-static psa_status_t fill_key_label(struct ps_object_t *obj, size_t *length)
+static psa_status_t fill_key_label(struct ps_object_t *obj, uint8_t *label)
{
psa_storage_uid_t uid = obj->header.crypto.ref.uid;
int32_t client_id = obj->header.crypto.ref.client_id;
- if (PS_CRYPTO_BUF_LEN < (sizeof(client_id) + sizeof(uid))) {
- return PSA_ERROR_BUFFER_TOO_SMALL;
- }
-
- memcpy(ps_crypto_buf, &client_id, sizeof(client_id));
- memcpy(ps_crypto_buf + sizeof(client_id), &uid, sizeof(uid));
-
- *length = sizeof(client_id) + sizeof(uid);
+ memcpy(label, &client_id, sizeof(client_id));
+ memcpy(label + sizeof(client_id), &uid, sizeof(uid));
return PSA_SUCCESS;
}
@@ -70,20 +62,19 @@
{
psa_status_t err;
uint8_t *p_obj_data = (uint8_t *)&obj->header.info;
- size_t out_len, label_length;
+ size_t out_len;
+ uint8_t label[sizeof(int32_t) + sizeof(psa_storage_uid_t)];
- err = fill_key_label(obj, &label_length);
+ err = fill_key_label(obj, label);
if (err != PSA_SUCCESS) {
return err;
}
- err = ps_crypto_setkey(ps_crypto_buf, label_length);
+ err = ps_crypto_setkey(label, sizeof(label));
if (err != PSA_SUCCESS) {
return err;
}
- (void)memcpy(ps_crypto_buf, p_obj_data, cur_size);
-
/* Use File ID as a part of the associated data to authenticate
* the object in the FS. The tag will be stored in the object table and
* not as a part of the object's data stored in the FS.
@@ -92,7 +83,7 @@
err = ps_crypto_auth_and_decrypt(&obj->header.crypto,
(const uint8_t *)&fid,
sizeof(fid),
- ps_crypto_buf,
+ p_obj_data,
cur_size,
p_obj_data,
sizeof(*obj) - sizeof(obj->header.crypto),
@@ -122,14 +113,15 @@
{
psa_status_t err;
uint8_t *p_obj_data = (uint8_t *)&obj->header.info;
- size_t out_len, label_length;
+ size_t out_len;
+ uint8_t label[sizeof(int32_t) + sizeof(psa_storage_uid_t)];
- err = fill_key_label(obj, &label_length);
+ err = fill_key_label(obj, label);
if (err != PSA_SUCCESS) {
return err;
}
- err = ps_crypto_setkey(ps_crypto_buf, label_length);
+ err = ps_crypto_setkey(label, sizeof(label));
if (err != PSA_SUCCESS) {
return err;
}
@@ -150,16 +142,14 @@
sizeof(fid),
p_obj_data,
cur_size,
- ps_crypto_buf,
- sizeof(ps_crypto_buf),
+ (uint8_t *)&obj->header.info,
+ PS_CRYPTO_BUF_LEN,
&out_len);
if (err != PSA_SUCCESS || out_len != cur_size) {
(void)ps_crypto_destroykey();
return PSA_ERROR_GENERIC_ERROR;
}
- (void)memcpy(p_obj_data, ps_crypto_buf, cur_size);
-
return ps_crypto_destroykey();
}
@@ -175,12 +165,9 @@
* In the psa_its_get, the buffer size is not checked. Check the buffer size
* here.
*/
- if (sizeof(ps_crypto_buf) < PS_MAX_ENCRYPTED_OBJ_SIZE + PS_IV_LEN_BYTES) {
- return PSA_ERROR_GENERIC_ERROR;
- }
err = psa_its_get(fid, PS_OBJECT_START_POSITION,
PS_MAX_ENCRYPTED_OBJ_SIZE + PS_IV_LEN_BYTES,
- (void *)ps_crypto_buf,
+ (void *)obj->header.crypto.ref.iv,
&data_length);
if (err != PSA_SUCCESS) {
return err;
@@ -192,10 +179,6 @@
* skip the padding byte.
*/
decrypt_size = data_length - sizeof(obj->header.crypto.ref.iv);
- memcpy(&obj->header.info, ps_crypto_buf, decrypt_size);
- memcpy(obj->header.crypto.ref.iv,
- ps_crypto_buf + decrypt_size,
- sizeof(obj->header.crypto.ref.iv));
/* Decrypt the object data */
err = ps_object_auth_decrypt(fid, decrypt_size, obj);
@@ -224,14 +207,11 @@
* Toolchains may add padding byte after iv array in crypto.ref structure.
* The padding byte shall not be written into the storage area.
*/
- (void)memcpy(ps_crypto_buf + wrt_size,
- obj->header.crypto.ref.iv,
- sizeof(obj->header.crypto.ref.iv));
wrt_size += sizeof(obj->header.crypto.ref.iv);
/* Write the encrypted object to the persistent area. The tag values is not
* copied as it is stored in the object table.
*/
- return psa_its_set(fid, wrt_size, (const void *)ps_crypto_buf,
+ return psa_its_set(fid, wrt_size, (const void *)obj->header.crypto.ref.iv,
PSA_STORAGE_FLAG_NONE);
}
diff --git a/secure_fw/partitions/protected_storage/ps_object_defs.h b/secure_fw/partitions/protected_storage/ps_object_defs.h
index 7ca7d33..7b02654 100644
--- a/secure_fw/partitions/protected_storage/ps_object_defs.h
+++ b/secure_fw/partitions/protected_storage/ps_object_defs.h
@@ -45,6 +45,8 @@
#define PS_MAX_OBJECT_DATA_SIZE PS_MAX_ASSET_SIZE
+#define PS_TAG_IV_LEN_MAX ((PS_TAG_LEN_BYTES > PS_IV_LEN_BYTES) ? \
+ PS_TAG_LEN_BYTES : PS_IV_LEN_BYTES)
/*!
* \struct ps_object_t
@@ -55,6 +57,7 @@
struct ps_object_t {
struct ps_obj_header_t header; /*!< Object header */
uint8_t data[PS_MAX_OBJECT_DATA_SIZE]; /*!< Object data */
+ uint8_t tag_iv[PS_TAG_IV_LEN_MAX];
};