xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision 03e07432b68f9d78dbad4b9a8af50705948e7893)
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 
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 
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  */
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 
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 
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 
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 
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 
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 
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 	uint32_t tee_curve = 0;
717 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
718 	TEE_Attribute tee_key_attr[1] = { };
719 	TEE_Result res = TEE_ERROR_GENERIC;
720 
721 	if (!proc_params || !*pub_head || !*priv_head)
722 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
723 
724 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
725 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
726 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
727 		EMSG("Unexpected attribute(s) found");
728 		trace_attributes("public-key", *pub_head);
729 		trace_attributes("private-key", *priv_head);
730 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
731 	}
732 
733 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
734 			      &a_ptr, &a_size) || !a_ptr) {
735 		EMSG("No EC_PARAMS attribute found in public key");
736 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
737 	}
738 
739 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
740 	if (!tee_size)
741 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
742 
743 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
744 
745 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 1);
746 
747 	res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
748 					  &tee_obj);
749 	if (res) {
750 		EMSG("Transient alloc failed with %#"PRIx32, res);
751 		return tee2pkcs_error(res);
752 	}
753 
754 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
755 	if (res) {
756 		rc = tee2pkcs_error(res);
757 		goto out;
758 	}
759 
760 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
761 	if (res) {
762 		rc = tee2pkcs_error(res);
763 		goto out;
764 	}
765 
766 	/* Private key needs the same EC_PARAMS as used by the public key */
767 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
768 	if (rc)
769 		goto out;
770 
771 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
772 				    tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
773 	if (rc)
774 		goto out;
775 
776 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
777 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
778 	if (rc)
779 		goto out;
780 
781 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
782 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
783 
784 out:
785 	if (tee_obj != TEE_HANDLE_NULL)
786 		TEE_CloseObject(tee_obj);
787 
788 	return rc;
789 }
790 
791 enum pkcs11_rc
792 pkcs2tee_proc_params_eddsa(struct active_processing *proc,
793 			   struct pkcs11_attribute_head *proc_params)
794 {
795 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
796 	uint32_t ctx_len = 0;
797 	uint32_t flag = 0;
798 	void *ctx_data = NULL;
799 	struct serialargs args = { };
800 	struct eddsa_processing_ctx *ctx = NULL;
801 
802 	serialargs_init(&args, proc_params->data, proc_params->size);
803 
804 	rc = serialargs_get_u32(&args, &flag);
805 	if (rc)
806 		return rc;
807 
808 	rc = serialargs_get_u32(&args, &ctx_len);
809 	if (rc)
810 		return rc;
811 
812 	rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
813 	if (rc)
814 		return rc;
815 
816 	if (serialargs_remaining_bytes(&args))
817 		return PKCS11_CKR_ARGUMENTS_BAD;
818 
819 	proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
820 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
821 	if (!proc->extra_ctx)
822 		return PKCS11_CKR_DEVICE_MEMORY;
823 
824 	ctx = proc->extra_ctx;
825 	ctx->ctx_len = ctx_len;
826 	ctx->flag = flag;
827 	TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
828 
829 	return PKCS11_CKR_OK;
830 }
831 
832 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
833 {
834 	TEE_OperationInfo info = { };
835 
836 	TEE_GetOperationInfo(op, &info);
837 
838 	switch (info.algorithm) {
839 	case TEE_ALG_ECDSA_P192:
840 		return 24;
841 	case TEE_ALG_ECDSA_P224:
842 		return 28;
843 	case TEE_ALG_ECDSA_P256:
844 		return 32;
845 	case TEE_ALG_ECDSA_P384:
846 		return 48;
847 	case TEE_ALG_ECDSA_P521:
848 		return 66;
849 	default:
850 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
851 		return 0;
852 	}
853 }
854 
855 enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
856 				   void **pub_data, size_t *pub_size)
857 {
858 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
859 	struct serialargs args = { };
860 	uint32_t word = 0;
861 	uint8_t byte = 0;
862 
863 	serialargs_init(&args, proc_params->data, proc_params->size);
864 
865 	/* Skip KDF */
866 	rc = serialargs_get_u32(&args, &word);
867 	if (rc)
868 		return rc;
869 
870 	/* Shared data size, shall be 0 */
871 	rc = serialargs_get_u32(&args, &word);
872 	if (rc || word)
873 		return rc;
874 
875 	/* Public data size and content */
876 	rc = serialargs_get_u32(&args, &word);
877 	if (rc || !word)
878 		return rc;
879 
880 	*pub_size = word;
881 
882 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
883 	if (rc)
884 		return rc;
885 
886 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
887 		return PKCS11_CKR_ARGUMENTS_BAD;
888 
889 	if (byte != 0x04) {
890 		EMSG("DER compressed public key format not yet supported");
891 		return PKCS11_CKR_ARGUMENTS_BAD;
892 	}
893 
894 	*pub_size -= sizeof(uint8_t);
895 
896 	if (*pub_size >= 0x80) {
897 		EMSG("DER long definitive form not yet supported");
898 		return PKCS11_CKR_ARGUMENTS_BAD;
899 	}
900 
901 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
902 	if (rc)
903 		return rc;
904 
905 	if (serialargs_remaining_bytes(&args))
906 		return PKCS11_CKR_ARGUMENTS_BAD;
907 
908 	return PKCS11_CKR_OK;
909 }
910 
911 enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
912 				  struct pkcs11_attribute_head *proc_params,
913 				  struct pkcs11_object *obj)
914 {
915 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
916 	struct serialargs args = { };
917 	uint32_t kdf = 0;
918 
919 	serialargs_init(&args, proc_params->data, proc_params->size);
920 
921 	rc = serialargs_get_u32(&args, &kdf);
922 	if (rc)
923 		return rc;
924 
925 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
926 	if (kdf != PKCS11_CKD_NULL) {
927 		DMSG("Only support CKD_NULL key derivation for ECDH");
928 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
929 	}
930 
931 	switch (get_object_key_bit_size(obj)) {
932 	case 192:
933 		*tee_id = TEE_ALG_ECDH_P192;
934 		break;
935 	case 224:
936 		*tee_id = TEE_ALG_ECDH_P224;
937 		break;
938 	case 256:
939 		*tee_id = TEE_ALG_ECDH_P256;
940 		break;
941 	case 384:
942 		*tee_id = TEE_ALG_ECDH_P384;
943 		break;
944 	case 521:
945 		*tee_id = TEE_ALG_ECDH_P521;
946 		break;
947 	default:
948 		TEE_Panic(0);
949 		break;
950 	}
951 
952 	return PKCS11_CKR_OK;
953 }
954