1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017, Linaro Limited 4 * Copyright (c) 2020, Arm Limited. 5 */ 6 #include <crypto/crypto.h> 7 #include <initcall.h> 8 #include <kernel/embedded_ts.h> 9 #include <kernel/ts_store.h> 10 #include <kernel/user_access.h> 11 #include <mempool.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <trace.h> 16 #include <utee_defines.h> 17 #include <util.h> 18 #include <zlib.h> 19 20 struct ts_store_handle { 21 const struct embedded_ts *ts; 22 size_t offs; 23 z_stream strm; 24 }; 25 26 static void *zalloc(void *opaque __unused, unsigned int items, 27 unsigned int size) 28 { 29 return mempool_alloc(mempool_default, items * size); 30 } 31 32 static void zfree(void *opaque __unused, void *address) 33 { 34 mempool_free(mempool_default, address); 35 } 36 37 static bool decompression_init(z_stream *strm, 38 const struct embedded_ts *ts) 39 { 40 int st = Z_OK; 41 42 strm->next_in = ts->ts; 43 strm->avail_in = ts->size; 44 strm->zalloc = zalloc; 45 strm->zfree = zfree; 46 st = inflateInit(strm); 47 if (st != Z_OK) { 48 EMSG("Decompression initialization error (%d)", st); 49 return false; 50 } 51 52 return true; 53 } 54 55 TEE_Result emb_ts_open(const TEE_UUID *uuid, 56 struct ts_store_handle **h, 57 const struct embedded_ts* 58 (*find_ts) (const TEE_UUID *uuid)) 59 { 60 struct ts_store_handle *handle = NULL; 61 const struct embedded_ts *ts = NULL; 62 63 ts = find_ts(uuid); 64 if (!ts) 65 return TEE_ERROR_ITEM_NOT_FOUND; 66 67 handle = calloc(1, sizeof(*handle)); 68 if (!handle) 69 return TEE_ERROR_OUT_OF_MEMORY; 70 71 if (ts->uncompressed_size) { 72 if (!decompression_init(&handle->strm, ts)) { 73 free(handle); 74 return TEE_ERROR_BAD_FORMAT; 75 } 76 } 77 handle->ts = ts; 78 *h = handle; 79 80 return TEE_SUCCESS; 81 } 82 83 TEE_Result emb_ts_get_size(const struct ts_store_handle *h, size_t *size) 84 { 85 const struct embedded_ts *ts = h->ts; 86 87 if (ts->uncompressed_size) 88 *size = ts->uncompressed_size; 89 else 90 *size = ts->size; 91 92 return TEE_SUCCESS; 93 } 94 95 TEE_Result emb_ts_get_tag(const struct ts_store_handle *h, 96 uint8_t *tag, unsigned int *tag_len) 97 { 98 TEE_Result res = TEE_SUCCESS; 99 void *ctx = NULL; 100 101 if (!tag || *tag_len < TEE_SHA256_HASH_SIZE) { 102 *tag_len = TEE_SHA256_HASH_SIZE; 103 return TEE_ERROR_SHORT_BUFFER; 104 } 105 *tag_len = TEE_SHA256_HASH_SIZE; 106 107 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 108 if (res) 109 return res; 110 res = crypto_hash_init(ctx); 111 if (res) 112 goto out; 113 res = crypto_hash_update(ctx, h->ts->ts, h->ts->size); 114 if (res) 115 goto out; 116 res = crypto_hash_final(ctx, tag, *tag_len); 117 out: 118 crypto_hash_free_ctx(ctx); 119 return res; 120 } 121 122 static TEE_Result read_uncompressed(struct ts_store_handle *h, void *data_core, 123 void *data_user, size_t len) 124 { 125 TEE_Result res = TEE_SUCCESS; 126 uint8_t *src = (uint8_t *)h->ts->ts + h->offs; 127 size_t next_offs = 0; 128 129 if (ADD_OVERFLOW(h->offs, len, &next_offs) || 130 next_offs > h->ts->size) 131 return TEE_ERROR_BAD_PARAMETERS; 132 if (data_core) 133 memcpy(data_core, src, len); 134 if (data_user) 135 res = copy_to_user(data_user, src, len); 136 if (!res) 137 h->offs = next_offs; 138 139 return res; 140 } 141 142 static TEE_Result read_compressed(struct ts_store_handle *h, void *data_core, 143 void *data_user, size_t len) 144 { 145 TEE_Result res = TEE_SUCCESS; 146 z_stream *strm = &h->strm; 147 size_t total = 0; 148 uint8_t *bb = NULL; 149 size_t bb_len = 0; 150 size_t out = 0; 151 int st = Z_OK; 152 153 /* Inflate into a 1kB bounce buffer */ 154 bb_len = MIN(len, 1024U); 155 bb = bb_alloc(bb_len); 156 if (!bb) { 157 EMSG("Out of memory"); 158 return TEE_ERROR_OUT_OF_MEMORY; 159 } 160 161 strm->avail_out = bb_len; 162 strm->next_out = bb; 163 164 /* 165 * Loop until we get as many bytes as requested, or an error occurs. 166 * inflate() returns: 167 * - Z_OK when progress was made, but neither the end of the input 168 * stream nor the end of the output buffer were met. 169 * - Z_STREAM_END when the end of the intput stream was reached. 170 * - Z_BUF_ERROR when there is still input to process but the output 171 * buffer is full (not a "hard" error, decompression can proceeed 172 * later). 173 */ 174 do { 175 out = strm->total_out; 176 st = inflate(strm, Z_SYNC_FLUSH); 177 out = strm->total_out - out; 178 FMSG("%zu bytes", out); 179 if (data_core) 180 memcpy((uint8_t *)data_core + total, bb, out); 181 if (data_user) { 182 res = copy_to_user((uint8_t *)data_user + total, bb, 183 out); 184 if (res) 185 goto out; 186 } 187 total += out; 188 /* 189 * Reset the pointer since we've just copied out the last 190 * data. 191 */ 192 strm->next_out = bb; 193 strm->avail_out = MIN(len - total, bb_len); 194 } while ((st == Z_OK || st == Z_BUF_ERROR) && (total != len)); 195 196 if (st != Z_OK && st != Z_STREAM_END) { 197 EMSG("Decompression error (%d)", st); 198 res = TEE_ERROR_GENERIC; 199 goto out; 200 } 201 res = TEE_SUCCESS; 202 out: 203 bb_free(bb, bb_len); 204 205 return res; 206 } 207 208 TEE_Result emb_ts_read(struct ts_store_handle *h, void *data_core, 209 void *data_user, size_t len) 210 { 211 if (h->ts->uncompressed_size) 212 return read_compressed(h, data_core, data_user, len); 213 else 214 return read_uncompressed(h, data_core, data_user, len); 215 } 216 217 void emb_ts_close(struct ts_store_handle *h) 218 { 219 if (h->ts->uncompressed_size) 220 inflateEnd(&h->strm); 221 free(h); 222 } 223 224