xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision 68045ae95313b78298e98fe4646a161e135ec17b)
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 		/*
392 		 * Standard does not have CKA_EC_POINT for EC private keys
393 		 * but that is required by TEE internal API. First try to get
394 		 * hidden EC POINT and for backwards compatibility then try to
395 		 * get CKA_EC_POINT value.
396 		 */
397 
398 		if (pkcs2tee_load_attr(&attrs[count],
399 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
400 				       obj, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT))
401 			count++;
402 		else if (pkcs2tee_load_attr(&attrs[count],
403 					    TEE_ATTR_ECC_PUBLIC_VALUE_X,
404 					    obj, PKCS11_CKA_EC_POINT))
405 			count++;
406 
407 		if (pkcs2tee_load_attr(&attrs[count],
408 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
409 				       obj, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT))
410 			count++;
411 		else if (pkcs2tee_load_attr(&attrs[count],
412 					    TEE_ATTR_ECC_PUBLIC_VALUE_Y,
413 					    obj, PKCS11_CKA_EC_POINT))
414 			count++;
415 
416 		if (count == 4)
417 			rc = PKCS11_CKR_OK;
418 
419 		break;
420 
421 	default:
422 		assert(0);
423 		break;
424 	}
425 
426 	if (rc == PKCS11_CKR_OK) {
427 		*tee_attrs = attrs;
428 		*tee_count = count;
429 	} else {
430 		TEE_Free(attrs);
431 	}
432 
433 	return rc;
434 }
435 
436 enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
437 				   struct pkcs11_attribute_head *proc_params,
438 				   struct pkcs11_object *obj)
439 {
440 	switch (proc_params->id) {
441 	case PKCS11_CKM_ECDSA:
442 	case PKCS11_CKM_ECDSA_SHA1:
443 	case PKCS11_CKM_ECDSA_SHA224:
444 	case PKCS11_CKM_ECDSA_SHA256:
445 	case PKCS11_CKM_ECDSA_SHA384:
446 	case PKCS11_CKM_ECDSA_SHA512:
447 		break;
448 	default:
449 		return PKCS11_CKR_GENERAL_ERROR;
450 	}
451 
452 	/*
453 	 * TODO: Fixing this in a way to support also other EC curves would
454 	 * require OP-TEE to be updated for newer version of GlobalPlatform API
455 	 */
456 	switch (get_object_key_bit_size(obj)) {
457 	case 192:
458 		*tee_id = TEE_ALG_ECDSA_P192;
459 		break;
460 	case 224:
461 		*tee_id = TEE_ALG_ECDSA_P224;
462 		break;
463 	case 256:
464 		*tee_id = TEE_ALG_ECDSA_P256;
465 		break;
466 	case 384:
467 		*tee_id = TEE_ALG_ECDSA_P384;
468 		break;
469 	case 521:
470 		*tee_id = TEE_ALG_ECDSA_P521;
471 		break;
472 	default:
473 		TEE_Panic(0);
474 		break;
475 	}
476 
477 	return PKCS11_CKR_OK;
478 }
479 
480 static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
481 					     struct obj_attrs **priv_head,
482 					     TEE_ObjectHandle tee_obj,
483 					     size_t tee_size)
484 {
485 	void *x_ptr = NULL;
486 	void *y_ptr = NULL;
487 	uint8_t *ecpoint = NULL;
488 	size_t x_size = 0;
489 	size_t y_size = 0;
490 	size_t psize = 0;
491 	size_t qsize = 0;
492 	size_t dersize = 0;
493 	size_t poffset = 0;
494 	size_t hsize = 0;
495 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
496 
497 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
498 				    tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
499 	if (rc)
500 		goto out;
501 
502 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
503 					  &x_ptr, &x_size);
504 	if (rc)
505 		goto out;
506 
507 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
508 					  &y_ptr, &y_size);
509 	if (rc)
510 		goto x_cleanup;
511 
512 	psize = (tee_size + 7) / 8;
513 	if (x_size > psize || y_size > psize) {
514 		rc = PKCS11_CKR_ARGUMENTS_BAD;
515 		goto y_cleanup;
516 	}
517 
518 	qsize = 1 + 2 * psize;
519 	if (qsize < 0x80) {
520 		/* DER short definitive form up to 127 bytes */
521 		dersize = qsize + 2;
522 		hsize = 2 /* der */ + 1 /* point compression */;
523 	} else if (qsize < 0x100) {
524 		/* DER long definitive form up to 255 bytes */
525 		dersize = qsize + 3;
526 		hsize = 3 /* der */ + 1 /* point compression */;
527 	} else {
528 		EMSG("Too long DER value");
529 		rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
530 		goto y_cleanup;
531 	}
532 
533 	ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
534 	if (!ecpoint) {
535 		rc = PKCS11_CKR_DEVICE_MEMORY;
536 		goto y_cleanup;
537 	}
538 
539 	if (qsize < 0x80) {
540 		/* DER encoding */
541 		ecpoint[0] = 0x04;
542 		ecpoint[1] = qsize & 0x7f;
543 
544 		/* Only UNCOMPRESSED ECPOINT is currently supported */
545 		ecpoint[2] = 0x04;
546 	} else if (qsize < 0x100) {
547 		/* DER encoding */
548 		ecpoint[0] = 0x04;
549 		ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
550 		ecpoint[2] = qsize & 0xFF;
551 
552 		/* Only UNCOMPRESSED ECPOINT is currently supported */
553 		ecpoint[3] = 0x04;
554 	}
555 
556 	poffset = 0;
557 	if (x_size < psize)
558 		poffset = psize - x_size;
559 	TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
560 
561 	poffset = 0;
562 	if (y_size < psize)
563 		poffset = psize - y_size;
564 	TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
565 
566 	/*
567 	 * Add PKCS11_CKA_OPTEE_HIDDEN_EC_POINT to private key object and
568 	 * standard PKCS11_CKA_EC_POINT to public key objects as
569 	 * TEE_PopulateTransientObject requires public x/y values
570 	 * for TEE_TYPE_ECDSA_KEYPAIR.
571 	 */
572 	rc = add_attribute(priv_head, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT,
573 			   ecpoint, dersize);
574 	if (rc)
575 		goto ecpoint_cleanup;
576 
577 	rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
578 
579 ecpoint_cleanup:
580 	TEE_Free(ecpoint);
581 y_cleanup:
582 	TEE_Free(y_ptr);
583 x_cleanup:
584 	TEE_Free(x_ptr);
585 out:
586 	return rc;
587 }
588 
589 enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
590 				struct obj_attrs **pub_head,
591 				struct obj_attrs **priv_head)
592 {
593 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
594 	void *a_ptr = NULL;
595 	uint32_t a_size = 0;
596 	uint32_t tee_size = 0;
597 	uint32_t tee_curve = 0;
598 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
599 	TEE_Attribute tee_key_attr[1] = { };
600 	TEE_Result res = TEE_ERROR_GENERIC;
601 
602 	if (!proc_params || !*pub_head || !*priv_head)
603 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
604 
605 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
606 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
607 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
608 		EMSG("Unexpected attribute(s) found");
609 		trace_attributes("public-key", *pub_head);
610 		trace_attributes("private-key", *priv_head);
611 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
612 	}
613 
614 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
615 			      &a_ptr, &a_size) || !a_ptr) {
616 		EMSG("No EC_PARAMS attribute found in public key");
617 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
618 	}
619 
620 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
621 	if (!tee_size)
622 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
623 
624 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
625 
626 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
627 
628 	/* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
629 	res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
630 					  &tee_obj);
631 	if (res) {
632 		EMSG("Transient alloc failed with %#"PRIx32, res);
633 		return tee2pkcs_error(res);
634 	}
635 
636 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
637 	if (res) {
638 		rc = tee2pkcs_error(res);
639 		goto out;
640 	}
641 
642 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
643 	if (res) {
644 		rc = tee2pkcs_error(res);
645 		goto out;
646 	}
647 
648 	/* Private key needs the same EC_PARAMS as used by the public key */
649 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
650 	if (rc)
651 		goto out;
652 
653 	rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
654 
655 out:
656 	if (tee_obj != TEE_HANDLE_NULL)
657 		TEE_CloseObject(tee_obj);
658 
659 	return rc;
660 }
661 
662 enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs,
663 					size_t *tee_count,
664 					struct pkcs11_object *obj)
665 {
666 	TEE_Attribute *attrs = NULL;
667 	size_t count = 0;
668 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
669 
670 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS);
671 
672 	switch (get_class(obj->attributes)) {
673 	case PKCS11_CKO_PUBLIC_KEY:
674 		attrs = TEE_Malloc(sizeof(TEE_Attribute),
675 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
676 		if (!attrs)
677 			return PKCS11_CKR_DEVICE_MEMORY;
678 
679 		if (pkcs2tee_load_attr(&attrs[count],
680 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
681 				       obj, PKCS11_CKA_EC_POINT))
682 			count++;
683 
684 		if (count == 1)
685 			rc = PKCS11_CKR_OK;
686 
687 		break;
688 
689 	case PKCS11_CKO_PRIVATE_KEY:
690 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
691 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
692 		if (!attrs)
693 			return PKCS11_CKR_DEVICE_MEMORY;
694 
695 		if (pkcs2tee_load_attr(&attrs[count],
696 				       TEE_ATTR_ED25519_PRIVATE_VALUE,
697 				       obj, PKCS11_CKA_VALUE))
698 			count++;
699 
700 		if (pkcs2tee_load_attr(&attrs[count],
701 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
702 				       obj, PKCS11_CKA_EC_POINT))
703 			count++;
704 
705 		if (count == 2)
706 			rc = PKCS11_CKR_OK;
707 
708 		break;
709 
710 	default:
711 		assert(0);
712 		break;
713 	}
714 
715 	if (rc == PKCS11_CKR_OK) {
716 		*tee_attrs = attrs;
717 		*tee_count = count;
718 	} else {
719 		TEE_Free(attrs);
720 	}
721 
722 	return rc;
723 }
724 
725 enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params,
726 				   struct obj_attrs **pub_head,
727 				   struct obj_attrs **priv_head)
728 {
729 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
730 	void *a_ptr = NULL;
731 	uint32_t a_size = 0;
732 	uint32_t tee_size = 0;
733 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
734 	TEE_Result res = TEE_ERROR_GENERIC;
735 
736 	if (!proc_params || !*pub_head || !*priv_head)
737 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
738 
739 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
740 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
741 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_POINT) ||
742 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
743 		EMSG("Unexpected attribute(s) found");
744 		trace_attributes("public-key", *pub_head);
745 		trace_attributes("private-key", *priv_head);
746 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
747 	}
748 
749 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
750 			      &a_ptr, &a_size) || !a_ptr) {
751 		EMSG("No EC_PARAMS attribute found in public key");
752 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
753 	}
754 
755 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
756 	if (!tee_size)
757 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
758 
759 	res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
760 					  &tee_obj);
761 	if (res) {
762 		EMSG("Transient alloc failed with %#"PRIx32, res);
763 		return tee2pkcs_error(res);
764 	}
765 
766 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
767 	if (res) {
768 		rc = tee2pkcs_error(res);
769 		goto out;
770 	}
771 
772 	res = TEE_GenerateKey(tee_obj, tee_size, NULL, 0);
773 	if (res) {
774 		rc = tee2pkcs_error(res);
775 		goto out;
776 	}
777 
778 	/* Private key needs the same EC_PARAMS as used by the public key */
779 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
780 	if (rc)
781 		goto out;
782 
783 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
784 				    tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
785 	if (rc)
786 		goto out;
787 
788 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
789 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
790 	if (rc)
791 		goto out;
792 
793 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
794 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
795 
796 out:
797 	if (tee_obj != TEE_HANDLE_NULL)
798 		TEE_CloseObject(tee_obj);
799 
800 	return rc;
801 }
802 
803 enum pkcs11_rc
804 pkcs2tee_proc_params_eddsa(struct active_processing *proc,
805 			   struct pkcs11_attribute_head *proc_params)
806 {
807 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
808 	uint32_t ctx_len = 0;
809 	uint32_t flag = 0;
810 	void *ctx_data = NULL;
811 	struct serialargs args = { };
812 	struct eddsa_processing_ctx *ctx = NULL;
813 
814 	serialargs_init(&args, proc_params->data, proc_params->size);
815 
816 	rc = serialargs_get_u32(&args, &flag);
817 	if (rc)
818 		return rc;
819 
820 	rc = serialargs_get_u32(&args, &ctx_len);
821 	if (rc)
822 		return rc;
823 
824 	rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
825 	if (rc)
826 		return rc;
827 
828 	if (serialargs_remaining_bytes(&args))
829 		return PKCS11_CKR_ARGUMENTS_BAD;
830 
831 	proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
832 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
833 	if (!proc->extra_ctx)
834 		return PKCS11_CKR_DEVICE_MEMORY;
835 
836 	ctx = proc->extra_ctx;
837 	ctx->ctx_len = ctx_len;
838 	ctx->flag = flag;
839 	TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
840 
841 	return PKCS11_CKR_OK;
842 }
843 
844 size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
845 {
846 	TEE_OperationInfo info = { };
847 
848 	TEE_GetOperationInfo(op, &info);
849 
850 	switch (info.algorithm) {
851 	case TEE_ALG_ECDSA_P192:
852 		return 24;
853 	case TEE_ALG_ECDSA_P224:
854 		return 28;
855 	case TEE_ALG_ECDSA_P256:
856 		return 32;
857 	case TEE_ALG_ECDSA_P384:
858 		return 48;
859 	case TEE_ALG_ECDSA_P521:
860 		return 66;
861 	default:
862 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
863 		return 0;
864 	}
865 }
866 
867 enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
868 				   void **pub_data, size_t *pub_size)
869 {
870 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
871 	struct serialargs args = { };
872 	uint32_t word = 0;
873 	uint8_t byte = 0;
874 
875 	serialargs_init(&args, proc_params->data, proc_params->size);
876 
877 	/* Skip KDF */
878 	rc = serialargs_get_u32(&args, &word);
879 	if (rc)
880 		return rc;
881 
882 	/* Shared data size, shall be 0 */
883 	rc = serialargs_get_u32(&args, &word);
884 	if (rc || word)
885 		return rc;
886 
887 	/* Public data size and content */
888 	rc = serialargs_get_u32(&args, &word);
889 	if (rc || !word)
890 		return rc;
891 
892 	*pub_size = word;
893 
894 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
895 	if (rc)
896 		return rc;
897 
898 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
899 		return PKCS11_CKR_ARGUMENTS_BAD;
900 
901 	if (byte != 0x04) {
902 		EMSG("DER compressed public key format not yet supported");
903 		return PKCS11_CKR_ARGUMENTS_BAD;
904 	}
905 
906 	*pub_size -= sizeof(uint8_t);
907 
908 	if (*pub_size >= 0x80) {
909 		EMSG("DER long definitive form not yet supported");
910 		return PKCS11_CKR_ARGUMENTS_BAD;
911 	}
912 
913 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
914 	if (rc)
915 		return rc;
916 
917 	if (serialargs_remaining_bytes(&args))
918 		return PKCS11_CKR_ARGUMENTS_BAD;
919 
920 	return PKCS11_CKR_OK;
921 }
922 
923 enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
924 				  struct pkcs11_attribute_head *proc_params,
925 				  struct pkcs11_object *obj)
926 {
927 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
928 	struct serialargs args = { };
929 	uint32_t kdf = 0;
930 
931 	serialargs_init(&args, proc_params->data, proc_params->size);
932 
933 	rc = serialargs_get_u32(&args, &kdf);
934 	if (rc)
935 		return rc;
936 
937 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
938 	if (kdf != PKCS11_CKD_NULL) {
939 		DMSG("Only support CKD_NULL key derivation for ECDH");
940 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
941 	}
942 
943 	switch (get_object_key_bit_size(obj)) {
944 	case 192:
945 		*tee_id = TEE_ALG_ECDH_P192;
946 		break;
947 	case 224:
948 		*tee_id = TEE_ALG_ECDH_P224;
949 		break;
950 	case 256:
951 		*tee_id = TEE_ALG_ECDH_P256;
952 		break;
953 	case 384:
954 		*tee_id = TEE_ALG_ECDH_P384;
955 		break;
956 	case 521:
957 		*tee_id = TEE_ALG_ECDH_P521;
958 		break;
959 	default:
960 		TEE_Panic(0);
961 		break;
962 	}
963 
964 	return PKCS11_CKR_OK;
965 }
966