1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 #include <kernel/cache_helpers.h> 6 #include <kernel/chip_services.h> 7 #include <kernel/tee_common_otp.h> 8 #include <kernel/tee_common.h> 9 #include <kernel/tee_misc.h> 10 #include <malloc.h> 11 #include <mm/core_memprot.h> 12 #include <stdio.h> 13 #include <trace.h> 14 15 static uint8_t tee_b2hs_add_base(uint8_t in) 16 { 17 if (in > 9) 18 return in + 55; 19 else 20 return in + 48; 21 } 22 23 static int tee_hs2b_rem_base(uint8_t in, uint8_t *out) 24 { 25 if (in < 48 || in > 70 || (in > 57 && in < 65)) 26 return -1; 27 28 if (in < 58) 29 *out = in - 48; 30 else 31 *out = in - 55; 32 33 return 0; 34 } 35 36 uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen) 37 { 38 uint32_t i = 0; 39 40 if (blen * 2 + 1 > hslen) 41 return 0; 42 43 for (; i < blen; i++) { 44 hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf); 45 hs[i * 2] = tee_b2hs_add_base(b[i] >> 4); 46 } 47 hs[blen * 2] = 0; 48 49 return blen * 2; 50 } 51 52 uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen) 53 { 54 uint32_t i = 0; 55 uint32_t len = TEE_HS2B_BBUF_SIZE(hslen); 56 uint8_t hi; 57 uint8_t lo; 58 59 if (len > blen) 60 return 0; 61 62 for (; i < len; i++) { 63 if (tee_hs2b_rem_base(hs[i * 2], &hi)) 64 return 0; 65 if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo)) 66 return 0; 67 b[i] = (hi << 4) + lo; 68 } 69 70 return len; 71 } 72 73 static bool is_valid_conf_and_notnull_size(paddr_t b, paddr_size_t bl, 74 paddr_t a, paddr_size_t al) 75 { 76 /* invalid config return false */ 77 if ((b - 1 + bl < b) || (a - 1 + al < a)) 78 return false; 79 /* null sized areas are never inside / outside / overlap */ 80 if (!bl || !al) 81 return false; 82 return true; 83 } 84 85 /* Returns true when buffer 'b' is fully contained in area 'a' */ 86 bool core_is_buffer_inside(paddr_t b, paddr_size_t bl, 87 paddr_t a, paddr_size_t al) 88 { 89 /* invalid config or "null size" return false */ 90 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 91 return false; 92 93 if ((b >= a) && (b - 1 + bl <= a - 1 + al)) 94 return true; 95 return false; 96 } 97 98 /* Returns true when buffer 'b' is fully outside area 'a' */ 99 bool core_is_buffer_outside(paddr_t b, paddr_size_t bl, 100 paddr_t a, paddr_size_t al) 101 { 102 /* invalid config or "null size" return false */ 103 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 104 return false; 105 106 if ((b + bl - 1 < a) || (b > a + al - 1)) 107 return true; 108 return false; 109 } 110 111 /* Returns true when buffer 'b' intersects area 'a' */ 112 bool core_is_buffer_intersect(paddr_t b, paddr_size_t bl, 113 paddr_t a, paddr_size_t al) 114 { 115 /* invalid config or "null size" return false */ 116 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 117 return false; 118 119 if ((b + bl - 1 < a) || (b > a + al - 1)) 120 return false; 121 return true; 122 } 123 124 void *alloc_cache_aligned(size_t size) 125 { 126 void *ptr = NULL; 127 size_t alloc_size = 0; 128 uint32_t cacheline_size = 0; 129 130 cacheline_size = cache_get_max_line_size(); 131 if (ROUNDUP_OVERFLOW(size, cacheline_size, &alloc_size)) 132 return NULL; 133 134 ptr = memalign(cacheline_size, alloc_size); 135 if (!ptr) 136 return NULL; 137 138 memset(ptr, 0, size); 139 140 return ptr; 141 } 142