File: tee_misc.c

package info (click to toggle)
optee-os 4.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,960 kB
  • sloc: ansic: 444,388; asm: 12,922; python: 3,719; makefile: 1,681; sh: 238
file content (139 lines) | stat: -rw-r--r-- 2,983 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 */
#include <kernel/cache_helpers.h>
#include <kernel/tee_common_otp.h>
#include <kernel/tee_common.h>
#include <kernel/tee_misc.h>
#include <malloc.h>
#include <mm/core_memprot.h>
#include <trace.h>

static uint8_t tee_b2hs_add_base(uint8_t in)
{
	if (in > 9)
		return in + 55;
	else
		return in + 48;
}

static int tee_hs2b_rem_base(uint8_t in, uint8_t *out)
{
	if (in < 48 || in > 70 || (in > 57 && in < 65))
		return -1;

	if (in < 58)
		*out = in - 48;
	else
		*out = in - 55;

	return 0;
}

uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen)
{
	uint32_t i = 0;

	if (blen * 2 + 1 > hslen)
		return 0;

	for (; i < blen; i++) {
		hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf);
		hs[i * 2] = tee_b2hs_add_base(b[i] >> 4);
	}
	hs[blen * 2] = 0;

	return blen * 2;
}

uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen)
{
	uint32_t i = 0;
	uint32_t len = TEE_HS2B_BBUF_SIZE(hslen);
	uint8_t hi;
	uint8_t lo;

	if (len > blen)
		return 0;

	for (; i < len; i++) {
		if (tee_hs2b_rem_base(hs[i * 2], &hi))
			return 0;
		if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo))
			return 0;
		b[i] = (hi << 4) + lo;
	}

	return len;
}

static bool is_valid_conf_and_notnull_size(paddr_t b, paddr_size_t bl,
					   paddr_t a, paddr_size_t al)
{
	/* invalid config return false */
	if ((b - 1 + bl < b) || (a - 1 + al < a))
		return false;
	/* null sized areas are never inside / outside / overlap */
	if (!bl || !al)
		return false;
	return true;
}

/* Returns true when buffer 'b' is fully contained in area 'a' */
bool core_is_buffer_inside(paddr_t b, paddr_size_t bl,
			   paddr_t a, paddr_size_t al)
{
	/* invalid config or "null size" return false */
	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
		return false;

	if ((b >= a) && (b - 1 + bl <= a - 1 + al))
		return true;
	return false;
}

/* Returns true when buffer 'b' is fully outside area 'a' */
bool core_is_buffer_outside(paddr_t b, paddr_size_t bl,
			    paddr_t a, paddr_size_t al)
{
	/* invalid config or "null size" return false */
	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
		return false;

	if ((b + bl - 1 < a) || (b > a + al - 1))
		return true;
	return false;
}

/* Returns true when buffer 'b' intersects area 'a' */
bool core_is_buffer_intersect(paddr_t b, paddr_size_t bl,
			      paddr_t a, paddr_size_t al)
{
	/* invalid config or "null size" return false */
	if (!is_valid_conf_and_notnull_size(b, bl, a, al))
		return false;

	if ((b + bl - 1 < a) || (b > a + al - 1))
		return false;
	return true;
}

void *alloc_cache_aligned(size_t size)
{
	void *ptr = NULL;
	size_t alloc_size = 0;
	uint32_t cacheline_size = 0;

	cacheline_size = cache_get_max_line_size();
	if (ROUNDUP2_OVERFLOW(size, cacheline_size, &alloc_size))
		return NULL;

	ptr = memalign(cacheline_size, alloc_size);
	if (!ptr)
		return NULL;

	memset(ptr, 0, size);

	return ptr;
}