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 "processing.h"
16
17 /*
18 * DER encoded EC parameters generated with script:
19 * ta/pkcs11/scripts/dump_ec_curve_params.sh
20 */
21
22 static const uint8_t prime192v1_name_der[] = {
23 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
24 0x01, 0x01,
25 };
26
27 static const uint8_t secp224r1_name_der[] = {
28 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21,
29 };
30
31 static const uint8_t prime256v1_name_der[] = {
32 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
33 0x01, 0x07,
34 };
35
36 static const uint8_t secp384r1_name_der[] = {
37 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
38 };
39
40 static const uint8_t secp521r1_name_der[] = {
41 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
42 };
43
44 static const uint8_t prime192v1_oid_der[] = {
45 0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24,
46 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
47 0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff,
48 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
49 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18,
51 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
52 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
54 0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c,
55 0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24,
56 0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46,
57 0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae,
58 0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95,
59 0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96,
60 0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e,
61 0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb,
62 0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd,
63 0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95,
64 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
65 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
66 0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff,
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
68 0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14,
69 0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02,
70 0x01, 0x01,
71 };
72
73 static const uint8_t secp224r1_oid_der[] = {
74 0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28,
75 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
76 0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff,
77 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
78 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
80 0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff,
81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
82 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
83 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
84 0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04,
85 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44,
86 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b,
87 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15,
88 0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7,
89 0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab,
90 0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04,
91 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
92 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
93 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
94 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88,
95 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
96 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
97 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
98 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
99 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
100 0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13,
101 0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02,
102 0x01, 0x01,
103 };
104
105 static const uint8_t prime256v1_oid_der[] = {
106 0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c,
107 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
108 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
109 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
112 0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20,
113 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
116 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
117 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
118 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
119 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
120 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
121 0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36,
122 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
123 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e,
124 0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2,
125 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
126 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
127 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45,
128 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
129 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
130 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
131 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
132 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff,
133 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
135 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
136 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02,
137 0x01, 0x01,
138 };
139
140 static const uint8_t secp384r1_oid_der[] = {
141 0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30,
142 0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
143 0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff,
144 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0xfe, 0xff, 0xff, 0xff,
148 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04,
150 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 0xff, 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 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
156 0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2,
157 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3,
158 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe,
159 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50,
160 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a,
161 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3,
162 0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35,
163 0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
164 0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd,
165 0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca,
166 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7,
167 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b,
168 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41,
169 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2,
170 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e,
171 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde,
172 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98,
173 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d,
174 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31,
175 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1,
176 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d,
177 0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00,
178 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
181 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
182 0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
183 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,
184 0x02, 0x01, 0x01,
185 };
186
187 static const uint8_t secp521r1_oid_der[] = {
188 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30,
189 0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
190 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
191 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81,
199 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
200 0xff, 0xff, 0xff, 0xff, 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, 0xfc, 0x04, 0x42, 0x00,
208 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
209 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
210 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
211 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
212 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
213 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
214 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
215 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
216 0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00,
217 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
218 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba,
219 0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e,
220 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
221 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64,
222 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28,
223 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
224 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d,
225 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48,
226 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
227 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18,
228 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
229 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
230 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
231 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
232 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
233 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
234 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
235 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
236 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
237 0xff, 0xff, 0xff, 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, 0xfa, 0x51, 0x86, 0x87, 0x83,
241 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
242 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8,
243 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e,
244 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
245 };
246
247 struct supported_ecc_curve {
248 const uint8_t *oid_der;
249 size_t oid_size;
250 const uint8_t *name_der;
251 size_t name_size;
252 size_t key_size;
253 uint32_t tee_id;
254 const char *label;
255 size_t label_size;
256 };
257
258 #define ECC_CURVE(_tee_id, _key_size, _label) \
259 { \
260 .tee_id = (_tee_id), \
261 .key_size = (_key_size), \
262 .oid_der = _label ## _oid_der, \
263 .oid_size = sizeof(_label ## _oid_der), \
264 .name_der = _label ## _name_der, \
265 .name_size = sizeof(_label ## _name_der), \
266 .label = #_label, \
267 .label_size = sizeof(#_label) - 1, \
268 }
269
270 static const struct supported_ecc_curve ec_curve_param[] = {
271 ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1),
272 ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1),
273 ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1),
274 ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1),
275 ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1),
276 };
277
get_curve(void * attr,size_t size)278 static const struct supported_ecc_curve *get_curve(void *attr, size_t size)
279 {
280 size_t idx = 0;
281
282 /* Weak: not a real DER parser: try by params then by named curve */
283 for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) {
284 const struct supported_ecc_curve *curve = ec_curve_param + idx;
285
286 if (size == curve->oid_size &&
287 !TEE_MemCompare(attr, curve->oid_der, curve->oid_size))
288 return curve;
289
290 if (size == curve->name_size &&
291 !TEE_MemCompare(attr, curve->name_der, curve->name_size))
292 return curve;
293 }
294
295 return NULL;
296 }
297
ec_params2tee_keysize(void * ec_params,size_t size)298 size_t ec_params2tee_keysize(void *ec_params, size_t size)
299 {
300 const struct supported_ecc_curve *curve = get_curve(ec_params, size);
301
302 if (!curve)
303 return 0;
304
305 return curve->key_size;
306 }
307
308 /*
309 * This function intentionally panics if the curve is not found.
310 * Use ec_params2tee_keysize() to check the curve is supported by
311 * the internal core API.
312 */
ec_params2tee_curve(void * ec_params,size_t size)313 uint32_t ec_params2tee_curve(void *ec_params, size_t size)
314 {
315 const struct supported_ecc_curve *curve = get_curve(ec_params, size);
316
317 assert(curve);
318
319 return curve->tee_id;
320 }
321
load_tee_ec_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)322 enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs,
323 size_t *tee_count,
324 struct pkcs11_object *obj)
325 {
326 TEE_Attribute *attrs = NULL;
327 size_t count = 0;
328 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
329
330 assert(get_key_type(obj->attributes) == PKCS11_CKK_EC);
331
332 switch (get_class(obj->attributes)) {
333 case PKCS11_CKO_PUBLIC_KEY:
334 attrs = TEE_Malloc(3 * sizeof(TEE_Attribute),
335 TEE_USER_MEM_HINT_NO_FILL_ZERO);
336 if (!attrs)
337 return PKCS11_CKR_DEVICE_MEMORY;
338
339 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
340 obj, PKCS11_CKA_EC_PARAMS))
341 count++;
342
343 if (pkcs2tee_load_attr(&attrs[count],
344 TEE_ATTR_ECC_PUBLIC_VALUE_X,
345 obj, PKCS11_CKA_EC_POINT))
346 count++;
347
348 if (pkcs2tee_load_attr(&attrs[count],
349 TEE_ATTR_ECC_PUBLIC_VALUE_Y,
350 obj, PKCS11_CKA_EC_POINT))
351 count++;
352
353 if (count == 3)
354 rc = PKCS11_CKR_OK;
355
356 break;
357
358 case PKCS11_CKO_PRIVATE_KEY:
359 attrs = TEE_Malloc(4 * sizeof(TEE_Attribute),
360 TEE_USER_MEM_HINT_NO_FILL_ZERO);
361 if (!attrs)
362 return PKCS11_CKR_DEVICE_MEMORY;
363
364 if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
365 obj, PKCS11_CKA_EC_PARAMS))
366 count++;
367
368 if (pkcs2tee_load_attr(&attrs[count],
369 TEE_ATTR_ECC_PRIVATE_VALUE,
370 obj, PKCS11_CKA_VALUE))
371 count++;
372
373 if (pkcs2tee_load_attr(&attrs[count],
374 TEE_ATTR_ECC_PUBLIC_VALUE_X,
375 obj, PKCS11_CKA_EC_POINT))
376 count++;
377
378 if (pkcs2tee_load_attr(&attrs[count],
379 TEE_ATTR_ECC_PUBLIC_VALUE_Y,
380 obj, PKCS11_CKA_EC_POINT))
381 count++;
382
383 if (count == 4)
384 rc = PKCS11_CKR_OK;
385
386 break;
387
388 default:
389 assert(0);
390 break;
391 }
392
393 if (rc == PKCS11_CKR_OK) {
394 *tee_attrs = attrs;
395 *tee_count = count;
396 } else {
397 TEE_Free(attrs);
398 }
399
400 return rc;
401 }
402
pkcs2tee_algo_ecdsa(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)403 enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
404 struct pkcs11_attribute_head *proc_params,
405 struct pkcs11_object *obj)
406 {
407 switch (proc_params->id) {
408 case PKCS11_CKM_ECDSA:
409 case PKCS11_CKM_ECDSA_SHA1:
410 case PKCS11_CKM_ECDSA_SHA224:
411 case PKCS11_CKM_ECDSA_SHA256:
412 case PKCS11_CKM_ECDSA_SHA384:
413 case PKCS11_CKM_ECDSA_SHA512:
414 break;
415 default:
416 return PKCS11_CKR_GENERAL_ERROR;
417 }
418
419 /*
420 * TODO: Fixing this in a way to support also other EC curves would
421 * require OP-TEE to be updated for newer version of GlobalPlatform API
422 */
423 switch (get_object_key_bit_size(obj)) {
424 case 192:
425 *tee_id = TEE_ALG_ECDSA_P192;
426 break;
427 case 224:
428 *tee_id = TEE_ALG_ECDSA_P224;
429 break;
430 case 256:
431 *tee_id = TEE_ALG_ECDSA_P256;
432 break;
433 case 384:
434 *tee_id = TEE_ALG_ECDSA_P384;
435 break;
436 case 521:
437 *tee_id = TEE_ALG_ECDSA_P521;
438 break;
439 default:
440 TEE_Panic(0);
441 break;
442 }
443
444 return PKCS11_CKR_OK;
445 }
446
tee2pkcs_ec_attributes(struct obj_attrs ** pub_head,struct obj_attrs ** priv_head,TEE_ObjectHandle tee_obj,size_t tee_size)447 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
448 struct obj_attrs **priv_head,
449 TEE_ObjectHandle tee_obj,
450 size_t tee_size)
451 {
452 void *x_ptr = NULL;
453 void *y_ptr = NULL;
454 uint8_t *ecpoint = NULL;
455 size_t x_size = 0;
456 size_t y_size = 0;
457 size_t psize = 0;
458 size_t qsize = 0;
459 size_t dersize = 0;
460 size_t poffset = 0;
461 size_t hsize = 0;
462 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
463
464 rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
465 tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
466 if (rc)
467 goto out;
468
469 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
470 &x_ptr, &x_size);
471 if (rc)
472 goto out;
473
474 rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
475 &y_ptr, &y_size);
476 if (rc)
477 goto x_cleanup;
478
479 psize = (tee_size + 7) / 8;
480 if (x_size > psize || y_size > psize) {
481 rc = PKCS11_CKR_ARGUMENTS_BAD;
482 goto y_cleanup;
483 }
484
485 qsize = 1 + 2 * psize;
486 if (qsize < 0x80) {
487 /* DER short definitive form up to 127 bytes */
488 dersize = qsize + 2;
489 hsize = 2 /* der */ + 1 /* point compression */;
490 } else if (qsize < 0x100) {
491 /* DER long definitive form up to 255 bytes */
492 dersize = qsize + 3;
493 hsize = 3 /* der */ + 1 /* point compression */;
494 } else {
495 EMSG("Too long DER value");
496 rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
497 goto y_cleanup;
498 }
499
500 ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
501 if (!ecpoint) {
502 rc = PKCS11_CKR_DEVICE_MEMORY;
503 goto y_cleanup;
504 }
505
506 if (qsize < 0x80) {
507 /* DER encoding */
508 ecpoint[0] = 0x04;
509 ecpoint[1] = qsize & 0x7f;
510
511 /* Only UNCOMPRESSED ECPOINT is currently supported */
512 ecpoint[2] = 0x04;
513 } else if (qsize < 0x100) {
514 /* DER encoding */
515 ecpoint[0] = 0x04;
516 ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
517 ecpoint[2] = qsize & 0xFF;
518
519 /* Only UNCOMPRESSED ECPOINT is currently supported */
520 ecpoint[3] = 0x04;
521 }
522
523 poffset = 0;
524 if (x_size < psize)
525 poffset = psize - x_size;
526 TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
527
528 poffset = 0;
529 if (y_size < psize)
530 poffset = psize - y_size;
531 TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
532
533 /*
534 * Add EC_POINT on both private and public key objects as
535 * TEE_PopulateTransientObject requires public x/y values
536 * for TEE_TYPE_ECDSA_KEYPAIR.
537 */
538 rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
539 if (rc)
540 goto ecpoint_cleanup;
541
542 rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
543
544 ecpoint_cleanup:
545 TEE_Free(ecpoint);
546 y_cleanup:
547 TEE_Free(y_ptr);
548 x_cleanup:
549 TEE_Free(x_ptr);
550 out:
551 return rc;
552 }
553
generate_ec_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)554 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
555 struct obj_attrs **pub_head,
556 struct obj_attrs **priv_head)
557 {
558 enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
559 void *a_ptr = NULL;
560 uint32_t a_size = 0;
561 uint32_t tee_size = 0;
562 uint32_t tee_curve = 0;
563 TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
564 TEE_Attribute tee_key_attr[1] = { };
565 TEE_Result res = TEE_ERROR_GENERIC;
566
567 if (!proc_params || !*pub_head || !*priv_head)
568 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
569
570 if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
571 remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
572 remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
573 EMSG("Unexpected attribute(s) found");
574 trace_attributes("public-key", *pub_head);
575 trace_attributes("private-key", *priv_head);
576 return PKCS11_CKR_TEMPLATE_INCONSISTENT;
577 }
578
579 if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
580 &a_ptr, &a_size) || !a_ptr) {
581 EMSG("No EC_PARAMS attribute found in public key");
582 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
583 }
584
585 tee_size = ec_params2tee_keysize(a_ptr, a_size);
586 if (!tee_size)
587 return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
588
589 tee_curve = ec_params2tee_curve(a_ptr, a_size);
590
591 TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
592
593 /* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
594 res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
595 &tee_obj);
596 if (res) {
597 EMSG("Transient alloc failed with %#"PRIx32, res);
598 return tee2pkcs_error(res);
599 }
600
601 res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
602 if (res) {
603 rc = tee2pkcs_error(res);
604 goto out;
605 }
606
607 res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
608 if (res) {
609 rc = tee2pkcs_error(res);
610 goto out;
611 }
612
613 /* Private key needs the same EC_PARAMS as used by the public key */
614 rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
615 if (rc)
616 goto out;
617
618 rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
619
620 out:
621 if (tee_obj != TEE_HANDLE_NULL)
622 TEE_CloseObject(tee_obj);
623
624 return rc;
625 }
626
ecdsa_get_input_max_byte_size(TEE_OperationHandle op)627 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
628 {
629 TEE_OperationInfo info = { };
630
631 TEE_GetOperationInfo(op, &info);
632
633 switch (info.algorithm) {
634 case TEE_ALG_ECDSA_P192:
635 return 24;
636 case TEE_ALG_ECDSA_P224:
637 return 28;
638 case TEE_ALG_ECDSA_P256:
639 return 32;
640 case TEE_ALG_ECDSA_P384:
641 return 48;
642 case TEE_ALG_ECDSA_P521:
643 return 66;
644 default:
645 DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
646 return 0;
647 }
648 }
649