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