TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ps_encrypted_object.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "ps_encrypted_object.h"
9 
10 #include <stddef.h>
11 
14 #include "tfm_memory_utils.h"
15 #include "ps_object_defs.h"
16 #include "ps_utils.h"
17 
18 /* Gets the size of data to encrypt */
19 #define PS_ENCRYPT_SIZE(plaintext_size) \
20  ((plaintext_size) + PS_OBJECT_HEADER_SIZE - sizeof(union ps_crypto_t))
21 
22 #define PS_OBJECT_START_POSITION 0
23 
24 /* Buffer to store the maximum encrypted object */
25 /* FIXME: Do partial encrypt/decrypt to reduce the size of internal buffer */
26 #define PS_MAX_ENCRYPTED_OBJ_SIZE PS_ENCRYPT_SIZE(PS_MAX_OBJECT_DATA_SIZE)
27 
28 /* FIXME: add the tag length to the crypto buffer size to account for the tag
29  * being appended to the ciphertext by the crypto layer.
30  */
31 #define PS_CRYPTO_BUF_LEN (PS_MAX_ENCRYPTED_OBJ_SIZE + PS_TAG_LEN_BYTES)
32 
33 static uint8_t ps_crypto_buf[PS_CRYPTO_BUF_LEN];
34 
48 static psa_status_t ps_object_auth_decrypt(uint32_t fid,
49  uint32_t cur_size,
50  struct ps_object_t *obj)
51 {
52  psa_status_t err;
53  uint8_t *p_obj_data = (uint8_t *)&obj->header.info;
54  size_t out_len;
55 
56  err = ps_crypto_setkey();
57  if (err != PSA_SUCCESS) {
58  return err;
59  }
60 
61  (void)tfm_memcpy(ps_crypto_buf, p_obj_data, cur_size);
62 
63  /* Use File ID as a part of the associated data to authenticate
64  * the object in the FS. The tag will be stored in the object table and
65  * not as a part of the object's data stored in the FS.
66  */
67 
68  err = ps_crypto_auth_and_decrypt(&obj->header.crypto,
69  (const uint8_t *)&fid,
70  sizeof(fid),
71  ps_crypto_buf,
72  cur_size,
73  p_obj_data,
74  sizeof(*obj) - sizeof(obj->header.crypto),
75  &out_len);
76  if (err != PSA_SUCCESS || out_len != cur_size) {
77  (void)ps_crypto_destroykey();
79  }
80 
81  return ps_crypto_destroykey();
82 }
83 
95 static psa_status_t ps_object_auth_encrypt(uint32_t fid,
96  uint32_t cur_size,
97  struct ps_object_t *obj)
98 {
99  psa_status_t err;
100  uint8_t *p_obj_data = (uint8_t *)&obj->header.info;
101  size_t out_len;
102 
103  err = ps_crypto_setkey();
104  if (err != PSA_SUCCESS) {
105  return err;
106  }
107 
108  /* FIXME: should have an IV per object with key diversification */
109  /* Get a new IV for each encryption */
110  ps_crypto_get_iv(&obj->header.crypto);
111 
112  /* Use File ID as a part of the associated data to authenticate
113  * the object in the FS. The tag will be stored in the object table and
114  * not as a part of the object's data stored in the FS.
115  */
116 
117  err = ps_crypto_encrypt_and_tag(&obj->header.crypto,
118  (const uint8_t *)&fid,
119  sizeof(fid),
120  p_obj_data,
121  cur_size,
122  ps_crypto_buf,
123  sizeof(ps_crypto_buf),
124  &out_len);
125  if (err != PSA_SUCCESS || out_len != cur_size) {
126  (void)ps_crypto_destroykey();
128  }
129 
130  (void)tfm_memcpy(p_obj_data, ps_crypto_buf, cur_size);
131 
132  return ps_crypto_destroykey();
133 }
134 
136 {
137  psa_status_t err;
138  uint32_t decrypt_size;
139  size_t data_length;
140 
141  /* Read the encrypted object from the the persistent area */
144  (void *)obj->header.crypto.ref.iv,
145  &data_length);
146  if (err != PSA_SUCCESS) {
147  return err;
148  }
149 
150  /* Get the decrypt size */
151  decrypt_size = data_length - sizeof(obj->header.crypto.ref.iv);
152 
153  /* Decrypt the object data */
154  err = ps_object_auth_decrypt(fid, decrypt_size, obj);
155  if (err != PSA_SUCCESS) {
156  return err;
157  }
158 
159  return PSA_SUCCESS;
160 }
161 
163 {
164  psa_status_t err;
165  uint32_t wrt_size;
166 
167  wrt_size = PS_ENCRYPT_SIZE(obj->header.info.current_size);
168 
169  /* Authenticate and encrypt the object */
170  err = ps_object_auth_encrypt(fid, wrt_size, obj);
171  if (err != PSA_SUCCESS) {
172  return err;
173  }
174 
175  wrt_size += sizeof(obj->header.crypto.ref.iv);
176 
177  /* Write the encrypted object to the persistent area. The tag values is not
178  * copied as it is stored in the object table.
179  */
180  return psa_its_set(fid, wrt_size, (const void *)obj->header.crypto.ref.iv,
182 }
#define PS_CRYPTO_BUF_LEN
psa_status_t ps_encrypted_object_read(uint32_t fid, struct ps_object_t *obj)
Reads object referenced by the object File ID.
#define PSA_SUCCESS
Definition: crypto_values.h:35
#define PS_ENCRYPT_SIZE(plaintext_size)
struct ps_object_info_t info
#define PS_MAX_OBJECT_SIZE
psa_status_t ps_crypto_setkey(void)
Sets the key to use for crypto operations for the current client.
psa_status_t ps_crypto_encrypt_and_tag(union ps_crypto_t *crypto, const uint8_t *add, size_t add_len, const uint8_t *in, size_t in_len, uint8_t *out, size_t out_size, size_t *out_len)
Encrypts and tags the given plaintext data.
psa_status_t psa_its_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size, void *p_data, size_t *p_data_length)
Retrieve data associated with a provided UID.
#define PSA_ERROR_GENERIC_ERROR
Definition: crypto_values.h:43
psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
Create a new, or modify an existing, uid/value pair.
#define PS_OBJECT_START_POSITION
psa_status_t ps_crypto_auth_and_decrypt(const union ps_crypto_t *crypto, const uint8_t *add, size_t add_len, uint8_t *in, size_t in_len, uint8_t *out, size_t out_size, size_t *out_len)
Decrypts and authenticates the given encrypted data.
__STATIC_INLINE void * tfm_memcpy(void *dest, const void *src, size_t num)
psa_status_t ps_encrypted_object_write(uint32_t fid, struct ps_object_t *obj)
Creates and writes a new encrypted object based on the given ps_object_t structure data...
struct ps_obj_header_t header
psa_status_t ps_crypto_destroykey(void)
Destroys the transient key used for crypto operations.
void ps_crypto_get_iv(union ps_crypto_t *crypto)
Gets a new IV value into the crypto union.
#define PSA_STORAGE_FLAG_NONE
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
The object to be written to the file system below. Made up of the object header and the object data...
uint32_t current_size