xref: /rk3399_ARM-atf/services/std_svc/rmmd/rmmd_attest.c (revision 0f9159b7ebb7e784a8ed998869ff21095fa105b1)
1*0f9159b7SSoby Mathew /*
2*0f9159b7SSoby Mathew  * Copyright (c) 2022, Arm Limited. All rights reserved.
3*0f9159b7SSoby Mathew  *
4*0f9159b7SSoby Mathew  * SPDX-License-Identifier: BSD-3-Clause
5*0f9159b7SSoby Mathew  */
6*0f9159b7SSoby Mathew #include <stdint.h>
7*0f9159b7SSoby Mathew #include <string.h>
8*0f9159b7SSoby Mathew #include <common/debug.h>
9*0f9159b7SSoby Mathew #include <lib/spinlock.h>
10*0f9159b7SSoby Mathew #include <lib/xlat_tables/xlat_tables_v2.h>
11*0f9159b7SSoby Mathew #include <plat/common/platform.h>
12*0f9159b7SSoby Mathew #include "rmmd_private.h"
13*0f9159b7SSoby Mathew #include <services/rmmd_svc.h>
14*0f9159b7SSoby Mathew 
15*0f9159b7SSoby Mathew static spinlock_t lock;
16*0f9159b7SSoby Mathew 
17*0f9159b7SSoby Mathew /* For printing Realm attestation token hash */
18*0f9159b7SSoby Mathew #define DIGITS_PER_BYTE				2UL
19*0f9159b7SSoby Mathew #define LENGTH_OF_TERMINATING_ZERO_IN_BYTES	1UL
20*0f9159b7SSoby Mathew #define BYTES_PER_LINE_BASE			4UL
21*0f9159b7SSoby Mathew 
22*0f9159b7SSoby Mathew static void print_challenge(uint8_t *hash, size_t hash_size)
23*0f9159b7SSoby Mathew {
24*0f9159b7SSoby Mathew 	size_t leftover;
25*0f9159b7SSoby Mathew 	/*
26*0f9159b7SSoby Mathew 	 * bytes_per_line is always a power of two, so it can be used to
27*0f9159b7SSoby Mathew 	 * construct mask with it when it is necessary to count remainder.
28*0f9159b7SSoby Mathew 	 *
29*0f9159b7SSoby Mathew 	 */
30*0f9159b7SSoby Mathew 	const size_t bytes_per_line = 1 << BYTES_PER_LINE_BASE;
31*0f9159b7SSoby Mathew 	char hash_text[(1 << BYTES_PER_LINE_BASE) * DIGITS_PER_BYTE +
32*0f9159b7SSoby Mathew 		LENGTH_OF_TERMINATING_ZERO_IN_BYTES];
33*0f9159b7SSoby Mathew 	const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
34*0f9159b7SSoby Mathew 				  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
35*0f9159b7SSoby Mathew 	unsigned int i;
36*0f9159b7SSoby Mathew 
37*0f9159b7SSoby Mathew 	for (i = 0U; i < hash_size; ++i) {
38*0f9159b7SSoby Mathew 		hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE] =
39*0f9159b7SSoby Mathew 			hex_chars[hash[i] >> 4];
40*0f9159b7SSoby Mathew 		hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE + 1] =
41*0f9159b7SSoby Mathew 			hex_chars[hash[i] & 0x0f];
42*0f9159b7SSoby Mathew 		if (((i + 1) & (bytes_per_line - 1)) == 0U) {
43*0f9159b7SSoby Mathew 			hash_text[bytes_per_line * DIGITS_PER_BYTE] = '\0';
44*0f9159b7SSoby Mathew 			VERBOSE("hash part %u = %s\n",
45*0f9159b7SSoby Mathew 				(i >> BYTES_PER_LINE_BASE) + 1, hash_text);
46*0f9159b7SSoby Mathew 		}
47*0f9159b7SSoby Mathew 	}
48*0f9159b7SSoby Mathew 
49*0f9159b7SSoby Mathew 	leftover = (size_t)i & (bytes_per_line - 1);
50*0f9159b7SSoby Mathew 
51*0f9159b7SSoby Mathew 	if (leftover != 0UL) {
52*0f9159b7SSoby Mathew 		hash_text[leftover * DIGITS_PER_BYTE] = '\0';
53*0f9159b7SSoby Mathew 		VERBOSE("hash part %u = %s\n", (i >> BYTES_PER_LINE_BASE) + 1,
54*0f9159b7SSoby Mathew 			hash_text);
55*0f9159b7SSoby Mathew 	}
56*0f9159b7SSoby Mathew }
57*0f9159b7SSoby Mathew 
58*0f9159b7SSoby Mathew /*
59*0f9159b7SSoby Mathew  * TODO: Have different error codes for different errors so that the caller can
60*0f9159b7SSoby Mathew  * differentiate various error cases.
61*0f9159b7SSoby Mathew  */
62*0f9159b7SSoby Mathew int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len, uint64_t challenge_hash_len)
63*0f9159b7SSoby Mathew {
64*0f9159b7SSoby Mathew 	int err;
65*0f9159b7SSoby Mathew 	uintptr_t va;
66*0f9159b7SSoby Mathew 	uint8_t temp_buf[SHA512_DIGEST_SIZE];
67*0f9159b7SSoby Mathew 
68*0f9159b7SSoby Mathew 	/*
69*0f9159b7SSoby Mathew 	 * TODO: Currently we don't validate incoming buf_pa. This is a
70*0f9159b7SSoby Mathew 	 * prototype and we will need to allocate static buffer for EL3-RMM
71*0f9159b7SSoby Mathew 	 * communication.
72*0f9159b7SSoby Mathew 	 */
73*0f9159b7SSoby Mathew 
74*0f9159b7SSoby Mathew 	/* We need a page of buffer to pass data */
75*0f9159b7SSoby Mathew 	if (*buf_len != PAGE_SIZE) {
76*0f9159b7SSoby Mathew 		ERROR("Invalid buffer length\n");
77*0f9159b7SSoby Mathew 		return RMMD_ERR_INVAL;
78*0f9159b7SSoby Mathew 	}
79*0f9159b7SSoby Mathew 
80*0f9159b7SSoby Mathew 	if ((challenge_hash_len != SHA256_DIGEST_SIZE) &&
81*0f9159b7SSoby Mathew 	    (challenge_hash_len != SHA384_DIGEST_SIZE) &&
82*0f9159b7SSoby Mathew 	    (challenge_hash_len != SHA512_DIGEST_SIZE)) {
83*0f9159b7SSoby Mathew 		ERROR("Invalid hash size: %lu\n", challenge_hash_len);
84*0f9159b7SSoby Mathew 		return RMMD_ERR_INVAL;
85*0f9159b7SSoby Mathew 	}
86*0f9159b7SSoby Mathew 
87*0f9159b7SSoby Mathew 	spin_lock(&lock);
88*0f9159b7SSoby Mathew 
89*0f9159b7SSoby Mathew 	/* Map the buffer that was provided by the RMM. */
90*0f9159b7SSoby Mathew 	err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
91*0f9159b7SSoby Mathew 					       MT_RW_DATA | MT_REALM);
92*0f9159b7SSoby Mathew 	if (err != 0) {
93*0f9159b7SSoby Mathew 		ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
94*0f9159b7SSoby Mathew 		      , err, (void *)buf_pa);
95*0f9159b7SSoby Mathew 		spin_unlock(&lock);
96*0f9159b7SSoby Mathew 		return RMMD_ERR_NOMEM;
97*0f9159b7SSoby Mathew 	}
98*0f9159b7SSoby Mathew 
99*0f9159b7SSoby Mathew 	(void)memcpy(temp_buf, (void *)va, challenge_hash_len);
100*0f9159b7SSoby Mathew 
101*0f9159b7SSoby Mathew 	print_challenge((uint8_t *)temp_buf, challenge_hash_len);
102*0f9159b7SSoby Mathew 
103*0f9159b7SSoby Mathew 	/* Get the platform token. */
104*0f9159b7SSoby Mathew 	err = plat_get_cca_attest_token(va,
105*0f9159b7SSoby Mathew 		buf_len, (uintptr_t)temp_buf, challenge_hash_len);
106*0f9159b7SSoby Mathew 
107*0f9159b7SSoby Mathew 	if (err != 0) {
108*0f9159b7SSoby Mathew 		ERROR("Failed to get platform token: %d.\n", err);
109*0f9159b7SSoby Mathew 		err = RMMD_ERR_UNK;
110*0f9159b7SSoby Mathew 	}
111*0f9159b7SSoby Mathew 
112*0f9159b7SSoby Mathew 	/* Unmap RMM memory. */
113*0f9159b7SSoby Mathew 	(void)mmap_remove_dynamic_region(va, PAGE_SIZE);
114*0f9159b7SSoby Mathew 	spin_unlock(&lock);
115*0f9159b7SSoby Mathew 
116*0f9159b7SSoby Mathew 	return err;
117*0f9159b7SSoby Mathew }
118*0f9159b7SSoby Mathew 
119