xref: /optee_os/core/kernel/tee_misc.c (revision 1bb929836182ecb96d2d9d268daa807c67596396)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include <stdio.h>
29 #include <kernel/tee_common.h>
30 #include <kernel/chip_services.h>
31 #include <kernel/tee_misc.h>
32 #include <mm/core_memprot.h>
33 #include <kernel/tee_common_otp.h>
34 #include <trace.h>
35 
36 static uint8_t tee_b2hs_add_base(uint8_t in)
37 {
38 	if (in > 9)
39 		return in + 55;
40 	else
41 		return in + 48;
42 }
43 
44 static int tee_hs2b_rem_base(uint8_t in, uint8_t *out)
45 {
46 	if (in < 48 || in > 70 || (in > 57 && in < 65))
47 		return -1;
48 
49 	if (in < 58)
50 		*out = in - 48;
51 	else
52 		*out = in - 55;
53 
54 	return 0;
55 }
56 
57 uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen)
58 {
59 	uint32_t i = 0;
60 
61 	if (blen * 2 + 1 > hslen)
62 		return 0;
63 
64 	for (; i < blen; i++) {
65 		hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf);
66 		hs[i * 2] = tee_b2hs_add_base(b[i] >> 4);
67 	}
68 	hs[blen * 2] = 0;
69 
70 	return blen * 2;
71 }
72 
73 uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen)
74 {
75 	uint32_t i = 0;
76 	uint32_t len = TEE_HS2B_BBUF_SIZE(hslen);
77 	uint8_t hi;
78 	uint8_t lo;
79 
80 	if (len > blen)
81 		return 0;
82 
83 	for (; i < len; i++) {
84 		if (tee_hs2b_rem_base(hs[i * 2], &hi))
85 			return 0;
86 		if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo))
87 			return 0;
88 		b[i] = (hi << 4) + lo;
89 	}
90 
91 	return len;
92 }
93 
94 static bool is_valid_conf_and_notnull_size(
95 		vaddr_t b, size_t bl, vaddr_t a, size_t al)
96 {
97 	/* invalid config return false */
98 	if ((b - 1 + bl < b) || (a - 1 + al < a))
99 		return false;
100 	/* null sized areas are never inside / outside / overlap */
101 	if (!bl || !al)
102 		return false;
103 	return true;
104 }
105 
106 /* Returns true when buffer 'b' is fully contained in area 'a' */
107 bool _core_is_buffer_inside(vaddr_t b, size_t bl, vaddr_t a, size_t al)
108 {
109 	/* invalid config or "null size" return false */
110 	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
111 		return false;
112 
113 	if ((b >= a) && (b - 1 + bl <= a - 1 + al))
114 		return true;
115 	return false;
116 }
117 
118 /* Returns true when buffer 'b' is fully contained in area 'a' */
119 bool _core_is_buffer_outside(vaddr_t b, size_t bl, vaddr_t a, size_t al)
120 {
121 	/* invalid config or "null size" return false */
122 	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
123 		return false;
124 
125 	if ((b + bl <= a) || (b >= a + al))
126 		return true;
127 	return false;
128 }
129 
130 /* Returns true when buffer 'b' intersects area 'a' */
131 bool _core_is_buffer_intersect(vaddr_t b, size_t bl, vaddr_t a, size_t al)
132 {
133 	/* invalid config or "null size" return false */
134 	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
135 		return false;
136 
137 	if ((b + bl <= a) || (b >= a + al))
138 		return false;
139 	return true;
140 }
141