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