1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2017-2020, Linaro Limited
4 */
5
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <tee_api_defines.h>
9 #include <tee_internal_api.h>
10 #include <tee_internal_api_extensions.h>
11 #include <util.h>
12
13 #include "attributes.h"
14 #include "object.h"
15 #include "pkcs11_token.h"
16 #include "processing.h"
17
18 /*
19 * DER encoded EC parameters generated with script:
20 * ta/pkcs11/scripts/dump_ec_curve_params.sh
21 */
22
23 static const uint8_t prime192v1_name_der[] = {
24 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
25 0x01, 0x01,
26 };
27
28 static const uint8_t secp224r1_name_der[] = {
29 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21,
30 };
31
32 static const uint8_t prime256v1_name_der[] = {
33 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
34 0x01, 0x07,
35 };
36
37 static const uint8_t secp384r1_name_der[] = {
38 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
39 };
40
41 static const uint8_t secp521r1_name_der[] = {
42 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
43 };
44
45 static const uint8_t prime192v1_oid_der[] = {
46 0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24,
47 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
48 0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
51 0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18,
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
55 0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c,
56 0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24,
57 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46,
58 0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae,
59 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95,
60 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96,
61 0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e,
62 0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb,
63 0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd,
64 0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95,
65 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
66 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
67 0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff,
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
69 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14,
70 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02,
71 0x01, 0x01,
72 };
73
74 static const uint8_t secp224r1_oid_der[] = {
75 0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28,
76 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
77 0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
81 0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff,
82 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
83 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
84 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
85 0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04,
86 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44,
87 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b,
88 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15,
89 0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7,
90 0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab,
91 0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04,
92 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
93 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
94 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
95 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88,
96 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
97 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
98 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
99 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
100 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
101 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13,
102 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02,
103 0x01, 0x01,
104 };
105
106 static const uint8_t prime256v1_oid_der[] = {
107 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c,
108 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
109 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
110 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
113 0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20,
114 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
117 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
118 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
119 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
120 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
121 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
122 0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36,
123 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
124 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e,
125 0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2,
126 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
127 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
128 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45,
129 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
130 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
131 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
132 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
133 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff,
134 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
135 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
136 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
137 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02,
138 0x01, 0x01,
139 };
140
141 static const uint8_t secp384r1_oid_der[] = {
142 0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30,
143 0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
144 0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
147 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
148 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
149 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04,
151 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
157 0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2,
158 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3,
159 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe,
160 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50,
161 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a,
162 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3,
163 0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35,
164 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
165 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd,
166 0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca,
167 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7,
168 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b,
169 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41,
170 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2,
171 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e,
172 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde,
173 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98,
174 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d,
175 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31,
176 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1,
177 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d,
178 0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00,
179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
181 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
182 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
183 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
184 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,
185 0x02, 0x01, 0x01,
186 };
187
188 static const uint8_t secp521r1_oid_der[] = {
189 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30,
190 0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
191 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
192 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
193 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
194 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
195 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
196 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
197 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
198 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x81,
200 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
201 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
202 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
205 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
207 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
208 0xff, 0xff, 0xff, 0xff, 0xfc, 0x04, 0x42, 0x00,
209 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
210 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
211 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
212 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
213 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
214 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
215 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
216 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
217 0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00,
218 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
219 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba,
220 0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e,
221 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
222 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64,
223 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28,
224 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
225 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d,
226 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48,
227 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
228 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18,
229 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
230 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
231 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
232 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
233 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
234 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
235 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
236 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
237 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
238 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
239 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
240 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
241 0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83,
242 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
243 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8,
244 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e,
245 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
246 };
247
248 /*
249 * Edwards curves may be specified in two flavours:
250 * - as a PrintableString 'edwards25519' or 'edwards448'
251 * - as an OID, DER encoded ASN.1 Object
252 */
253
254 static const uint8_t ed25519_name_der[] = {
255 0x13, 0x0c, 'e', 'd', 'w', 'a', 'r', 'd', 's',
256 '2', '5', '5', '1', '9',
257 };
258
259 static const uint8_t ed25519_oid_der[] = {
260 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda,
261 0x47, 0x0f, 0x01,
262 };
263
264 struct supported_ecc_curve {
265 const uint8_t *oid_der;
266 size_t oid_size;
267 const uint8_t *name_der;
268 size_t name_size;
269 size_t key_size;
270 uint32_t tee_id;
271 const char *label;
272 size_t label_size;
273 };
274
275 #define ECC_CURVE(_tee_id, _key_size, _label) \
276 { \
277 .tee_id = (_tee_id), \
278 .key_size = (_key_size), \
279 .oid_der = _label ## _oid_der, \
280 .oid_size = sizeof(_label ## _oid_der), \
281 .name_der = _label ## _name_der, \
282 .name_size = sizeof(_label ## _name_der), \
283 .label = #_label, \
284 .label_size = sizeof(#_label) - 1, \
285 }
286
287 static const struct supported_ecc_curve ec_curve_param[] = {
288 ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1),
289 ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1),
290 ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1),
291 ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1),
292 ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1),
293 ECC_CURVE(TEE_ECC_CURVE_25519, 256, ed25519),
294 };
295
get_curve(void * attr,size_t size)296 static const struct supported_ecc_curve *get_curve(void *attr, size_t size)
297 {
298 size_t idx = 0;
299
300 /* Weak: not a real DER parser: try by params then by named curve */
301 for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) {
302 const struct supported_ecc_curve *curve = ec_curve_param + idx;
303
304 if (size == curve->oid_size &&
305 !TEE_MemCompare(attr, curve->oid_der, curve->oid_size))
306 return curve;
307
308 if (size == curve->name_size &&
309 !TEE_MemCompare(attr, curve->name_der, curve->name_size))
310 return curve;
311 }
312
313 return NULL;
314 }
315
ec_params2tee_keysize(void * ec_params,size_t size)316 size_t ec_params2tee_keysize(void *ec_params, size_t size)
317 {
318 const struct supported_ecc_curve *curve = get_curve(ec_params, size);
319
320 if (!curve)
321 return 0;
322
323 return curve->key_size;
324 }
325
326 /*
327 * This function intentionally panics if the curve is not found.
328 * Use ec_params2tee_keysize() to check the curve is supported by
329 * the internal core API.
330 */
ec_params2tee_curve(void * ec_params,size_t size)331 uint32_t ec_params2tee_curve(void *ec_params, size_t size)
332 {
333 const struct supported_ecc_curve *curve = get_curve(ec_params, size);
334
335 assert(curve);
336
337 return curve->tee_id;
338 }
339
load_tee_ec_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)340 enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs,
341 size_t *tee_count,
342 struct pkcs11_object *obj)
343 {
344 TEE_Attribute *attrs = NULL;
345 size_t count = 0;
346 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
347
348 assert(get_key_type(obj->attributes) == PKCS11_CKK_EC);
349
350 switch (get_class(obj->attributes)) {
351 case PKCS11_CKO_PUBLIC_KEY:
352 attrs = TEE_Malloc(3 * sizeof(TEE_Attribute),
353 TEE_USER_MEM_HINT_NO_FILL_ZERO);
354 if (!attrs)
355 return PKCS11_CKR_DEVICE_MEMORY;
356
357 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
358 obj, PKCS11_CKA_EC_PARAMS))
359 count++;
360
361 if (pkcs2tee_load_attr(&attrs[count],
362 TEE_ATTR_ECC_PUBLIC_VALUE_X,
363 obj, PKCS11_CKA_EC_POINT))
364 count++;
365
366 if (pkcs2tee_load_attr(&attrs[count],
367 TEE_ATTR_ECC_PUBLIC_VALUE_Y,
368 obj, PKCS11_CKA_EC_POINT))
369 count++;
370
371 if (count == 3)
372 rc = PKCS11_CKR_OK;
373
374 break;
375
376 case PKCS11_CKO_PRIVATE_KEY:
377 attrs = TEE_Malloc(4 * sizeof(TEE_Attribute),
378 TEE_USER_MEM_HINT_NO_FILL_ZERO);
379 if (!attrs)
380 return PKCS11_CKR_DEVICE_MEMORY;
381
382 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
383 obj, PKCS11_CKA_EC_PARAMS))
384 count++;
385
386 if (pkcs2tee_load_attr(&attrs[count],
387 TEE_ATTR_ECC_PRIVATE_VALUE,
388 obj, PKCS11_CKA_VALUE))
389 count++;
390
391 if (pkcs2tee_load_attr(&attrs[count],
392 TEE_ATTR_ECC_PUBLIC_VALUE_X,
393 obj, PKCS11_CKA_EC_POINT))
394 count++;
395
396 if (pkcs2tee_load_attr(&attrs[count],
397 TEE_ATTR_ECC_PUBLIC_VALUE_Y,
398 obj, PKCS11_CKA_EC_POINT))
399 count++;
400
401 if (count == 4)
402 rc = PKCS11_CKR_OK;
403
404 break;
405
406 default:
407 assert(0);
408 break;
409 }
410
411 if (rc == PKCS11_CKR_OK) {
412 *tee_attrs = attrs;
413 *tee_count = count;
414 } else {
415 TEE_Free(attrs);
416 }
417
418 return rc;
419 }
420
pkcs2tee_algo_ecdsa(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)421 enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
422 struct pkcs11_attribute_head *proc_params,
423 struct pkcs11_object *obj)
424 {
425 switch (proc_params->id) {
426 case PKCS11_CKM_ECDSA:
427 case PKCS11_CKM_ECDSA_SHA1:
428 case PKCS11_CKM_ECDSA_SHA224:
429 case PKCS11_CKM_ECDSA_SHA256:
430 case PKCS11_CKM_ECDSA_SHA384:
431 case PKCS11_CKM_ECDSA_SHA512:
432 break;
433 default:
434 return PKCS11_CKR_GENERAL_ERROR;
435 }
436
437 /*
438 * TODO: Fixing this in a way to support also other EC curves would
439 * require OP-TEE to be updated for newer version of GlobalPlatform API
440 */
441 switch (get_object_key_bit_size(obj)) {
442 case 192:
443 *tee_id = TEE_ALG_ECDSA_P192;
444 break;
445 case 224:
446 *tee_id = TEE_ALG_ECDSA_P224;
447 break;
448 case 256:
449 *tee_id = TEE_ALG_ECDSA_P256;
450 break;
451 case 384:
452 *tee_id = TEE_ALG_ECDSA_P384;
453 break;
454 case 521:
455 *tee_id = TEE_ALG_ECDSA_P521;
456 break;
457 default:
458 TEE_Panic(0);
459 break;
460 }
461
462 return PKCS11_CKR_OK;
463 }
464
tee2pkcs_ec_attributes(struct obj_attrs ** pub_head,struct obj_attrs ** priv_head,TEE_ObjectHandle tee_obj,size_t tee_size)465 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
466 struct obj_attrs **priv_head,
467 TEE_ObjectHandle tee_obj,
468 size_t tee_size)
469 {
470 void *x_ptr = NULL;
471 void *y_ptr = NULL;
472 uint8_t *ecpoint = NULL;
473 size_t x_size = 0;
474 size_t y_size = 0;
475 size_t psize = 0;
476 size_t qsize = 0;
477 size_t dersize = 0;
478 size_t poffset = 0;
479 size_t hsize = 0;
480 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
481
482 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
483 tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
484 if (rc)
485 goto out;
486
487 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
488 &x_ptr, &x_size);
489 if (rc)
490 goto out;
491
492 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
493 &y_ptr, &y_size);
494 if (rc)
495 goto x_cleanup;
496
497 psize = (tee_size + 7) / 8;
498 if (x_size > psize || y_size > psize) {
499 rc = PKCS11_CKR_ARGUMENTS_BAD;
500 goto y_cleanup;
501 }
502
503 qsize = 1 + 2 * psize;
504 if (qsize < 0x80) {
505 /* DER short definitive form up to 127 bytes */
506 dersize = qsize + 2;
507 hsize = 2 /* der */ + 1 /* point compression */;
508 } else if (qsize < 0x100) {
509 /* DER long definitive form up to 255 bytes */
510 dersize = qsize + 3;
511 hsize = 3 /* der */ + 1 /* point compression */;
512 } else {
513 EMSG("Too long DER value");
514 rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
515 goto y_cleanup;
516 }
517
518 ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
519 if (!ecpoint) {
520 rc = PKCS11_CKR_DEVICE_MEMORY;
521 goto y_cleanup;
522 }
523
524 if (qsize < 0x80) {
525 /* DER encoding */
526 ecpoint[0] = 0x04;
527 ecpoint[1] = qsize & 0x7f;
528
529 /* Only UNCOMPRESSED ECPOINT is currently supported */
530 ecpoint[2] = 0x04;
531 } else if (qsize < 0x100) {
532 /* DER encoding */
533 ecpoint[0] = 0x04;
534 ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
535 ecpoint[2] = qsize & 0xFF;
536
537 /* Only UNCOMPRESSED ECPOINT is currently supported */
538 ecpoint[3] = 0x04;
539 }
540
541 poffset = 0;
542 if (x_size < psize)
543 poffset = psize - x_size;
544 TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
545
546 poffset = 0;
547 if (y_size < psize)
548 poffset = psize - y_size;
549 TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
550
551 /*
552 * Add EC_POINT on both private and public key objects as
553 * TEE_PopulateTransientObject requires public x/y values
554 * for TEE_TYPE_ECDSA_KEYPAIR.
555 */
556 rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
557 if (rc)
558 goto ecpoint_cleanup;
559
560 rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
561
562 ecpoint_cleanup:
563 TEE_Free(ecpoint);
564 y_cleanup:
565 TEE_Free(y_ptr);
566 x_cleanup:
567 TEE_Free(x_ptr);
568 out:
569 return rc;
570 }
571
generate_ec_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)572 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
573 struct obj_attrs **pub_head,
574 struct obj_attrs **priv_head)
575 {
576 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
577 void *a_ptr = NULL;
578 uint32_t a_size = 0;
579 uint32_t tee_size = 0;
580 uint32_t tee_curve = 0;
581 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
582 TEE_Attribute tee_key_attr[1] = { };
583 TEE_Result res = TEE_ERROR_GENERIC;
584
585 if (!proc_params || !*pub_head || !*priv_head)
586 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
587
588 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
589 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
590 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
591 EMSG("Unexpected attribute(s) found");
592 trace_attributes("public-key", *pub_head);
593 trace_attributes("private-key", *priv_head);
594 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
595 }
596
597 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
598 &a_ptr, &a_size) || !a_ptr) {
599 EMSG("No EC_PARAMS attribute found in public key");
600 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
601 }
602
603 tee_size = ec_params2tee_keysize(a_ptr, a_size);
604 if (!tee_size)
605 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
606
607 tee_curve = ec_params2tee_curve(a_ptr, a_size);
608
609 TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
610
611 /* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
612 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
613 &tee_obj);
614 if (res) {
615 EMSG("Transient alloc failed with %#"PRIx32, res);
616 return tee2pkcs_error(res);
617 }
618
619 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
620 if (res) {
621 rc = tee2pkcs_error(res);
622 goto out;
623 }
624
625 res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
626 if (res) {
627 rc = tee2pkcs_error(res);
628 goto out;
629 }
630
631 /* Private key needs the same EC_PARAMS as used by the public key */
632 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
633 if (rc)
634 goto out;
635
636 rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
637
638 out:
639 if (tee_obj != TEE_HANDLE_NULL)
640 TEE_CloseObject(tee_obj);
641
642 return rc;
643 }
644
load_tee_eddsa_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)645 enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs,
646 size_t *tee_count,
647 struct pkcs11_object *obj)
648 {
649 TEE_Attribute *attrs = NULL;
650 size_t count = 0;
651 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
652
653 assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS);
654
655 switch (get_class(obj->attributes)) {
656 case PKCS11_CKO_PUBLIC_KEY:
657 attrs = TEE_Malloc(sizeof(TEE_Attribute),
658 TEE_USER_MEM_HINT_NO_FILL_ZERO);
659 if (!attrs)
660 return PKCS11_CKR_DEVICE_MEMORY;
661
662 if (pkcs2tee_load_attr(&attrs[count],
663 TEE_ATTR_ED25519_PUBLIC_VALUE,
664 obj, PKCS11_CKA_EC_POINT))
665 count++;
666
667 if (count == 1)
668 rc = PKCS11_CKR_OK;
669
670 break;
671
672 case PKCS11_CKO_PRIVATE_KEY:
673 attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
674 TEE_USER_MEM_HINT_NO_FILL_ZERO);
675 if (!attrs)
676 return PKCS11_CKR_DEVICE_MEMORY;
677
678 if (pkcs2tee_load_attr(&attrs[count],
679 TEE_ATTR_ED25519_PRIVATE_VALUE,
680 obj, PKCS11_CKA_VALUE))
681 count++;
682
683 if (pkcs2tee_load_attr(&attrs[count],
684 TEE_ATTR_ED25519_PUBLIC_VALUE,
685 obj, PKCS11_CKA_EC_POINT))
686 count++;
687
688 if (count == 2)
689 rc = PKCS11_CKR_OK;
690
691 break;
692
693 default:
694 assert(0);
695 break;
696 }
697
698 if (rc == PKCS11_CKR_OK) {
699 *tee_attrs = attrs;
700 *tee_count = count;
701 } else {
702 TEE_Free(attrs);
703 }
704
705 return rc;
706 }
707
generate_eddsa_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)708 enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params,
709 struct obj_attrs **pub_head,
710 struct obj_attrs **priv_head)
711 {
712 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
713 void *a_ptr = NULL;
714 uint32_t a_size = 0;
715 uint32_t tee_size = 0;
716 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
717 TEE_Result res = TEE_ERROR_GENERIC;
718
719 if (!proc_params || !*pub_head || !*priv_head)
720 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
721
722 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
723 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
724 remove_empty_attribute(priv_head, PKCS11_CKA_EC_POINT) ||
725 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
726 EMSG("Unexpected attribute(s) found");
727 trace_attributes("public-key", *pub_head);
728 trace_attributes("private-key", *priv_head);
729 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
730 }
731
732 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
733 &a_ptr, &a_size) || !a_ptr) {
734 EMSG("No EC_PARAMS attribute found in public key");
735 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
736 }
737
738 tee_size = ec_params2tee_keysize(a_ptr, a_size);
739 if (!tee_size)
740 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
741
742 res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
743 &tee_obj);
744 if (res) {
745 EMSG("Transient alloc failed with %#"PRIx32, res);
746 return tee2pkcs_error(res);
747 }
748
749 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
750 if (res) {
751 rc = tee2pkcs_error(res);
752 goto out;
753 }
754
755 res = TEE_GenerateKey(tee_obj, tee_size, NULL, 0);
756 if (res) {
757 rc = tee2pkcs_error(res);
758 goto out;
759 }
760
761 /* Private key needs the same EC_PARAMS as used by the public key */
762 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
763 if (rc)
764 goto out;
765
766 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
767 tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
768 if (rc)
769 goto out;
770
771 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
772 tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
773 if (rc)
774 goto out;
775
776 rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
777 tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
778
779 out:
780 if (tee_obj != TEE_HANDLE_NULL)
781 TEE_CloseObject(tee_obj);
782
783 return rc;
784 }
785
786 enum pkcs11_rc
pkcs2tee_proc_params_eddsa(struct active_processing * proc,struct pkcs11_attribute_head * proc_params)787 pkcs2tee_proc_params_eddsa(struct active_processing *proc,
788 struct pkcs11_attribute_head *proc_params)
789 {
790 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
791 uint32_t ctx_len = 0;
792 uint32_t flag = 0;
793 void *ctx_data = NULL;
794 struct serialargs args = { };
795 struct eddsa_processing_ctx *ctx = NULL;
796
797 serialargs_init(&args, proc_params->data, proc_params->size);
798
799 rc = serialargs_get_u32(&args, &flag);
800 if (rc)
801 return rc;
802
803 rc = serialargs_get_u32(&args, &ctx_len);
804 if (rc)
805 return rc;
806
807 rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
808 if (rc)
809 return rc;
810
811 if (serialargs_remaining_bytes(&args))
812 return PKCS11_CKR_ARGUMENTS_BAD;
813
814 proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
815 TEE_USER_MEM_HINT_NO_FILL_ZERO);
816 if (!proc->extra_ctx)
817 return PKCS11_CKR_DEVICE_MEMORY;
818
819 ctx = proc->extra_ctx;
820 ctx->ctx_len = ctx_len;
821 ctx->flag = flag;
822 TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
823
824 return PKCS11_CKR_OK;
825 }
826
ecdsa_get_input_max_byte_size(TEE_OperationHandle op)827 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
828 {
829 TEE_OperationInfo info = { };
830
831 TEE_GetOperationInfo(op, &info);
832
833 switch (info.algorithm) {
834 case TEE_ALG_ECDSA_P192:
835 return 24;
836 case TEE_ALG_ECDSA_P224:
837 return 28;
838 case TEE_ALG_ECDSA_P256:
839 return 32;
840 case TEE_ALG_ECDSA_P384:
841 return 48;
842 case TEE_ALG_ECDSA_P521:
843 return 66;
844 default:
845 DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
846 return 0;
847 }
848 }
849
pkcs2tee_param_ecdh(struct pkcs11_attribute_head * proc_params,void ** pub_data,size_t * pub_size)850 enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
851 void **pub_data, size_t *pub_size)
852 {
853 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
854 struct serialargs args = { };
855 uint32_t word = 0;
856 uint8_t byte = 0;
857
858 serialargs_init(&args, proc_params->data, proc_params->size);
859
860 /* Skip KDF */
861 rc = serialargs_get_u32(&args, &word);
862 if (rc)
863 return rc;
864
865 /* Shared data size, shall be 0 */
866 rc = serialargs_get_u32(&args, &word);
867 if (rc || word)
868 return rc;
869
870 /* Public data size and content */
871 rc = serialargs_get_u32(&args, &word);
872 if (rc || !word)
873 return rc;
874
875 *pub_size = word;
876
877 rc = serialargs_get(&args, &byte, sizeof(uint8_t));
878 if (rc)
879 return rc;
880
881 if (byte != 0x02 && byte != 0x03 && byte != 0x04)
882 return PKCS11_CKR_ARGUMENTS_BAD;
883
884 if (byte != 0x04) {
885 EMSG("DER compressed public key format not yet supported");
886 return PKCS11_CKR_ARGUMENTS_BAD;
887 }
888
889 *pub_size -= sizeof(uint8_t);
890
891 if (*pub_size >= 0x80) {
892 EMSG("DER long definitive form not yet supported");
893 return PKCS11_CKR_ARGUMENTS_BAD;
894 }
895
896 rc = serialargs_get_ptr(&args, pub_data, *pub_size);
897 if (rc)
898 return rc;
899
900 if (serialargs_remaining_bytes(&args))
901 return PKCS11_CKR_ARGUMENTS_BAD;
902
903 return PKCS11_CKR_OK;
904 }
905
pkcs2tee_algo_ecdh(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)906 enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
907 struct pkcs11_attribute_head *proc_params,
908 struct pkcs11_object *obj)
909 {
910 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
911 struct serialargs args = { };
912 uint32_t kdf = 0;
913
914 serialargs_init(&args, proc_params->data, proc_params->size);
915
916 rc = serialargs_get_u32(&args, &kdf);
917 if (rc)
918 return rc;
919
920 /* Remaining arguments are extracted by pkcs2tee_param_ecdh */
921 if (kdf != PKCS11_CKD_NULL) {
922 DMSG("Only support CKD_NULL key derivation for ECDH");
923 return PKCS11_CKR_MECHANISM_PARAM_INVALID;
924 }
925
926 switch (get_object_key_bit_size(obj)) {
927 case 192:
928 *tee_id = TEE_ALG_ECDH_P192;
929 break;
930 case 224:
931 *tee_id = TEE_ALG_ECDH_P224;
932 break;
933 case 256:
934 *tee_id = TEE_ALG_ECDH_P256;
935 break;
936 case 384:
937 *tee_id = TEE_ALG_ECDH_P384;
938 break;
939 case 521:
940 *tee_id = TEE_ALG_ECDH_P521;
941 break;
942 default:
943 TEE_Panic(0);
944 break;
945 }
946
947 return PKCS11_CKR_OK;
948 }
949