1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #include <assert.h>
7 #include <attestation.h>
8 #include <attestation_priv.h>
9 #include <debug.h>
10 #include <errno.h>
11 #include <fpu_helpers.h>
12 #include <mbedtls/ecp.h>
13 #include <mbedtls/memory_buffer_alloc.h>
14 #include <memory_alloc.h>
15 #include <sizes.h>
16 
17 /*
18  * Memory buffer for the allocator during key initialization.
19  *
20  * Used to compute the public key and setup a PRNG object per CPU. PRNGs are
21  * needed for key blinding during EC signing.
22  *
23  * Memory requirements:
24  * +------------------------+-------+ ------------------------+
25  * |                        |  MAX  |  Persisting allocation  |
26  * +------------------------+-------+-------------------------+
27  * | Public key computation |  2.4K |         0.4K            |
28  * +------------------------+-------+-------------------------+
29  * |      PRNG setup        |  6.1K |          3.7K           |
30  * +------------------------+-------+-------------------------+
31  *
32  * Measured with:
33  *	src/lib/memory_buffer_alloc.c: mbedtls_memory_buffer_alloc_status()
34  */
35 #define INIT_HEAP_PAGES		3
36 
37 static unsigned char mem_buf[INIT_HEAP_PAGES * SZ_4K]
38 					__aligned(sizeof(unsigned long));
39 
40 static bool attest_initialized;
41 
42 struct buffer_alloc_ctx init_ctx;
43 
attestation_init(void)44 int attestation_init(void)
45 {
46 	int ret;
47 
48 	/*
49 	 * Associate the allocated heap for mbedtls with the current CPU.
50 	 */
51 	buffer_alloc_ctx_assign(&init_ctx);
52 
53 	fpu_save_my_state();
54 
55 	FPU_ALLOW(mbedtls_memory_buffer_alloc_init(mem_buf, sizeof(mem_buf)));
56 
57 	/*
58 	 * Set the number of max operations per ECC signing iteration
59 	 * Check for effective minimum values for
60 	 *  - ext/mbedtls/include/mbedtls/ecp.h:493
61 	 *
62 	 * This adjusts the length of a single signing loop.
63 	 */
64 	FPU_ALLOW(mbedtls_ecp_set_max_ops(ECP_MAX_OPS));
65 
66 	FPU_ALLOW(ret = attest_rnd_prng_init());
67 	if (ret != 0) {
68 		return ret;
69 	}
70 
71 	/* Retrieve the platform key from root world */
72 	FPU_ALLOW(ret = attest_init_realm_attestation_key());
73 	if (ret != 0) {
74 		return ret;
75 	}
76 
77 	fpu_restore_my_state();
78 
79 	/* Retrieve the platform token from root world */
80 	ret = attest_setup_platform_token();
81 	if (ret != 0) {
82 		return ret;
83 	}
84 
85 	buffer_alloc_ctx_unassign();
86 
87 	attest_initialized = true;
88 
89 	return 0;
90 }
91 
attestation_heap_ctx_init(unsigned char * buf,size_t buf_size)92 int attestation_heap_ctx_init(unsigned char *buf, size_t buf_size)
93 {
94 	assert(buf != NULL);
95 
96 	if (attest_initialized == false) {
97 		return -EINVAL;
98 	}
99 
100 	/* Initialise the mbedTLS heap */
101 	fpu_save_my_state();
102 	FPU_ALLOW(mbedtls_memory_buffer_alloc_init(buf, buf_size));
103 	fpu_restore_my_state();
104 
105 	return 0;
106 }
107 
attestation_heap_ctx_assign_pe(struct buffer_alloc_ctx * ctx)108 int attestation_heap_ctx_assign_pe(struct buffer_alloc_ctx *ctx)
109 {
110 	assert(ctx != NULL);
111 
112 	if (attest_initialized == false) {
113 		return -EINVAL;
114 	}
115 
116 	/*
117 	 * Associate the buffer_alloc_ctx to this CPU
118 	 */
119 	buffer_alloc_ctx_assign(ctx);
120 	return 0;
121 }
122 
attestation_heap_ctx_unassign_pe(struct buffer_alloc_ctx * ctx)123 int attestation_heap_ctx_unassign_pe(struct buffer_alloc_ctx *ctx)
124 {
125 	assert(ctx != NULL);
126 
127 	if (attest_initialized == false) {
128 		return -EINVAL;
129 	}
130 
131 	buffer_alloc_ctx_unassign();
132 	return 0;
133 }
134 
attestation_heap_reinit_pe(unsigned char * buf,size_t buf_size)135 inline int attestation_heap_reinit_pe(unsigned char *buf, size_t buf_size)
136 {
137 	fpu_save_my_state();
138 	FPU_ALLOW(mbedtls_memory_buffer_alloc_init(buf, buf_size));
139 	fpu_restore_my_state();
140 
141 	return 0;
142 }
143