blob: 355b03464354a733719355eb7fe6f9cc9645bf72 [file] [log] [blame]
Soby Mathew294e1cf2022-03-22 16:19:39 +00001/*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <stdint.h>
7#include <string.h>
8#include <common/debug.h>
9#include <lib/spinlock.h>
10#include <lib/xlat_tables/xlat_tables_v2.h>
11#include <plat/common/platform.h>
12#include "rmmd_private.h"
13#include <services/rmmd_svc.h>
14
15static spinlock_t lock;
16
17/* For printing Realm attestation token hash */
18#define DIGITS_PER_BYTE 2UL
19#define LENGTH_OF_TERMINATING_ZERO_IN_BYTES 1UL
20#define BYTES_PER_LINE_BASE 4UL
21
22static void print_challenge(uint8_t *hash, size_t hash_size)
23{
24 size_t leftover;
25 /*
26 * bytes_per_line is always a power of two, so it can be used to
27 * construct mask with it when it is necessary to count remainder.
28 *
29 */
30 const size_t bytes_per_line = 1 << BYTES_PER_LINE_BASE;
31 char hash_text[(1 << BYTES_PER_LINE_BASE) * DIGITS_PER_BYTE +
32 LENGTH_OF_TERMINATING_ZERO_IN_BYTES];
33 const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
34 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
35 unsigned int i;
36
37 for (i = 0U; i < hash_size; ++i) {
38 hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE] =
39 hex_chars[hash[i] >> 4];
40 hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE + 1] =
41 hex_chars[hash[i] & 0x0f];
42 if (((i + 1) & (bytes_per_line - 1)) == 0U) {
43 hash_text[bytes_per_line * DIGITS_PER_BYTE] = '\0';
44 VERBOSE("hash part %u = %s\n",
45 (i >> BYTES_PER_LINE_BASE) + 1, hash_text);
46 }
47 }
48
49 leftover = (size_t)i & (bytes_per_line - 1);
50
51 if (leftover != 0UL) {
52 hash_text[leftover * DIGITS_PER_BYTE] = '\0';
53 VERBOSE("hash part %u = %s\n", (i >> BYTES_PER_LINE_BASE) + 1,
54 hash_text);
55 }
56}
57
58/*
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010059 * Helper function to validate that the buffer base and length are
60 * within range.
Soby Mathew294e1cf2022-03-22 16:19:39 +000061 */
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010062static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
Soby Mathew294e1cf2022-03-22 16:19:39 +000063{
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010064 unsigned long shared_buf_page;
65 uintptr_t shared_buf_base;
Soby Mathew294e1cf2022-03-22 16:19:39 +000066
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010067 (void)plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
Soby Mathew294e1cf2022-03-22 16:19:39 +000068
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010069 shared_buf_page = shared_buf_base & ~PAGE_SIZE_MASK;
70
71 /* Validate the buffer pointer */
72 if ((buf_pa & ~PAGE_SIZE_MASK) != shared_buf_page) {
73 ERROR("Buffer PA out of range\n");
74 return E_RMM_BAD_ADDR;
Soby Mathew294e1cf2022-03-22 16:19:39 +000075 }
76
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010077 /* Validate the size of the shared area */
78 if (((buf_pa + buf_len - 1UL) & ~PAGE_SIZE_MASK) != shared_buf_page) {
79 ERROR("Invalid buffer length\n");
80 return E_RMM_INVAL;
Soby Mathew294e1cf2022-03-22 16:19:39 +000081 }
82
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010083 return 0; /* No error */
84}
85
86int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
87 uint64_t c_size)
88{
89 int err;
90 uint8_t temp_buf[SHA512_DIGEST_SIZE];
Soby Mathew294e1cf2022-03-22 16:19:39 +000091
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010092 err = validate_buffer_params(buf_pa, *buf_size);
Soby Mathew294e1cf2022-03-22 16:19:39 +000093 if (err != 0) {
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010094 return err;
Soby Mathew294e1cf2022-03-22 16:19:39 +000095 }
96
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +010097 if ((c_size != SHA256_DIGEST_SIZE) &&
98 (c_size != SHA384_DIGEST_SIZE) &&
99 (c_size != SHA512_DIGEST_SIZE)) {
100 ERROR("Invalid hash size: %lu\n", c_size);
101 return E_RMM_INVAL;
102 }
103
104 spin_lock(&lock);
Soby Mathew294e1cf2022-03-22 16:19:39 +0000105
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100106 (void)memcpy(temp_buf, (void *)buf_pa, c_size);
107
108 print_challenge((uint8_t *)temp_buf, c_size);
Soby Mathew294e1cf2022-03-22 16:19:39 +0000109
110 /* Get the platform token. */
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100111 err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
112 buf_size, (uintptr_t)temp_buf, c_size);
Soby Mathew294e1cf2022-03-22 16:19:39 +0000113
114 if (err != 0) {
115 ERROR("Failed to get platform token: %d.\n", err);
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100116 err = E_RMM_UNK;
Soby Mathew294e1cf2022-03-22 16:19:39 +0000117 }
118
Soby Mathew294e1cf2022-03-22 16:19:39 +0000119 spin_unlock(&lock);
120
121 return err;
122}
123
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100124int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
Soby Mathewf05d93a2022-03-22 16:21:19 +0000125 uint64_t ecc_curve)
126{
127 int err;
Soby Mathewf05d93a2022-03-22 16:21:19 +0000128
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100129 err = validate_buffer_params(buf_pa, *buf_size);
130 if (err != 0) {
131 return err;
Soby Mathewf05d93a2022-03-22 16:21:19 +0000132 }
133
134 if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
135 ERROR("Invalid ECC curve specified\n");
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100136 return E_RMM_INVAL;
Soby Mathewf05d93a2022-03-22 16:21:19 +0000137 }
138
139 spin_lock(&lock);
140
Soby Mathewf05d93a2022-03-22 16:21:19 +0000141 /* Get the Realm attestation key. */
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100142 err = plat_rmmd_get_cca_realm_attest_key((uintptr_t)buf_pa, buf_size,
143 (unsigned int)ecc_curve);
Soby Mathewf05d93a2022-03-22 16:21:19 +0000144 if (err != 0) {
145 ERROR("Failed to get attestation key: %d.\n", err);
Javier Almansa Sobrinodea652e2022-04-13 17:57:35 +0100146 err = E_RMM_UNK;
Soby Mathewf05d93a2022-03-22 16:21:19 +0000147 }
148
Soby Mathewf05d93a2022-03-22 16:21:19 +0000149 spin_unlock(&lock);
150
151 return err;
152}