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