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