xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision 03e07432b68f9d78dbad4b9a8af50705948e7893)
102b16804SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
202b16804SVesa Jääskeläinen /*
302b16804SVesa Jääskeläinen  * Copyright (c) 2017-2020, Linaro Limited
402b16804SVesa Jääskeläinen  */
502b16804SVesa Jääskeläinen 
602b16804SVesa Jääskeläinen #include <assert.h>
702b16804SVesa Jääskeläinen #include <pkcs11_ta.h>
802b16804SVesa Jääskeläinen #include <tee_api_defines.h>
902b16804SVesa Jääskeläinen #include <tee_internal_api.h>
10fb279d8bSVesa Jääskeläinen #include <tee_internal_api_extensions.h>
1102b16804SVesa Jääskeläinen #include <util.h>
1202b16804SVesa Jääskeläinen 
1302b16804SVesa Jääskeläinen #include "attributes.h"
14fb279d8bSVesa Jääskeläinen #include "object.h"
15*03e07432SValerii Chubar #include "pkcs11_token.h"
1602b16804SVesa Jääskeläinen #include "processing.h"
1702b16804SVesa Jääskeläinen 
1802b16804SVesa Jääskeläinen /*
1902b16804SVesa Jääskeläinen  * DER encoded EC parameters generated with script:
2002b16804SVesa Jääskeläinen  *   ta/pkcs11/scripts/dump_ec_curve_params.sh
2102b16804SVesa Jääskeläinen  */
2202b16804SVesa Jääskeläinen 
2302b16804SVesa Jääskeläinen static const uint8_t prime192v1_name_der[] = {
2402b16804SVesa Jääskeläinen 	0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
2502b16804SVesa Jääskeläinen 	0x01, 0x01,
2602b16804SVesa Jääskeläinen };
2702b16804SVesa Jääskeläinen 
2802b16804SVesa Jääskeläinen static const uint8_t secp224r1_name_der[] = {
2902b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21,
3002b16804SVesa Jääskeläinen };
3102b16804SVesa Jääskeläinen 
3202b16804SVesa Jääskeläinen static const uint8_t prime256v1_name_der[] = {
3302b16804SVesa Jääskeläinen 	0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
3402b16804SVesa Jääskeläinen 	0x01, 0x07,
3502b16804SVesa Jääskeläinen };
3602b16804SVesa Jääskeläinen 
3702b16804SVesa Jääskeläinen static const uint8_t secp384r1_name_der[] = {
3802b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
3902b16804SVesa Jääskeläinen };
4002b16804SVesa Jääskeläinen 
4102b16804SVesa Jääskeläinen static const uint8_t secp521r1_name_der[] = {
4202b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
4302b16804SVesa Jääskeläinen };
4402b16804SVesa Jääskeläinen 
4502b16804SVesa Jääskeläinen static const uint8_t prime192v1_oid_der[] = {
4602b16804SVesa Jääskeläinen 	0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24,
4702b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
4802b16804SVesa Jääskeläinen 	0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff,
4902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
5102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18,
5202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
5402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
5502b16804SVesa Jääskeläinen 	0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c,
5602b16804SVesa Jääskeläinen 	0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24,
5702b16804SVesa Jääskeläinen 	0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46,
5802b16804SVesa Jääskeläinen 	0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae,
5902b16804SVesa Jääskeläinen 	0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95,
6002b16804SVesa Jääskeläinen 	0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96,
6102b16804SVesa Jääskeläinen 	0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e,
6202b16804SVesa Jääskeläinen 	0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb,
6302b16804SVesa Jääskeläinen 	0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd,
6402b16804SVesa Jääskeläinen 	0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95,
6502b16804SVesa Jääskeläinen 	0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
6602b16804SVesa Jääskeläinen 	0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
6702b16804SVesa Jääskeläinen 	0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff,
6802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
6902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14,
7002b16804SVesa Jääskeläinen 	0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02,
7102b16804SVesa Jääskeläinen 	0x01, 0x01,
7202b16804SVesa Jääskeläinen };
7302b16804SVesa Jääskeläinen 
7402b16804SVesa Jääskeläinen static const uint8_t secp224r1_oid_der[] = {
7502b16804SVesa Jääskeläinen 	0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28,
7602b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
7702b16804SVesa Jääskeläinen 	0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff,
7802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
8002b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
8102b16804SVesa Jääskeläinen 	0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff,
8202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
8402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
8502b16804SVesa Jääskeläinen 	0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04,
8602b16804SVesa Jääskeläinen 	0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44,
8702b16804SVesa Jääskeläinen 	0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b,
8802b16804SVesa Jääskeläinen 	0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15,
8902b16804SVesa Jääskeläinen 	0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7,
9002b16804SVesa Jääskeläinen 	0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab,
9102b16804SVesa Jääskeläinen 	0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04,
9202b16804SVesa Jääskeläinen 	0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
9302b16804SVesa Jääskeläinen 	0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
9402b16804SVesa Jääskeläinen 	0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
9502b16804SVesa Jääskeläinen 	0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88,
9602b16804SVesa Jääskeläinen 	0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
9702b16804SVesa Jääskeläinen 	0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
9802b16804SVesa Jääskeläinen 	0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
9902b16804SVesa Jääskeläinen 	0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
10002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
10102b16804SVesa Jääskeläinen 	0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13,
10202b16804SVesa Jääskeläinen 	0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02,
10302b16804SVesa Jääskeläinen 	0x01, 0x01,
10402b16804SVesa Jääskeläinen };
10502b16804SVesa Jääskeläinen 
10602b16804SVesa Jääskeläinen static const uint8_t prime256v1_oid_der[] = {
10702b16804SVesa Jääskeläinen 	0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c,
10802b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
10902b16804SVesa Jääskeläinen 	0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
11002b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
11102b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20,
11402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
11502b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11602b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
11702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
11802b16804SVesa Jääskeläinen 	0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
11902b16804SVesa Jääskeläinen 	0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
12002b16804SVesa Jääskeläinen 	0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
12102b16804SVesa Jääskeläinen 	0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
12202b16804SVesa Jääskeläinen 	0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36,
12302b16804SVesa Jääskeläinen 	0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
12402b16804SVesa Jääskeläinen 	0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e,
12502b16804SVesa Jääskeläinen 	0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2,
12602b16804SVesa Jääskeläinen 	0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
12702b16804SVesa Jääskeläinen 	0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
12802b16804SVesa Jääskeläinen 	0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45,
12902b16804SVesa Jääskeläinen 	0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
13002b16804SVesa Jääskeläinen 	0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
13102b16804SVesa Jääskeläinen 	0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
13202b16804SVesa Jääskeläinen 	0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
13302b16804SVesa Jääskeläinen 	0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff,
13402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
13502b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
13602b16804SVesa Jääskeläinen 	0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
13702b16804SVesa Jääskeläinen 	0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02,
13802b16804SVesa Jääskeläinen 	0x01, 0x01,
13902b16804SVesa Jääskeläinen };
14002b16804SVesa Jääskeläinen 
14102b16804SVesa Jääskeläinen static const uint8_t secp384r1_oid_der[] = {
14202b16804SVesa Jääskeläinen 	0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30,
14302b16804SVesa Jääskeläinen 	0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
14402b16804SVesa Jääskeläinen 	0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff,
14502b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
14602b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
14702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
14802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
14902b16804SVesa Jääskeläinen 	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15002b16804SVesa Jääskeläinen 	0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04,
15102b16804SVesa Jääskeläinen 	0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15502b16804SVesa Jääskeläinen 	0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
15602b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
15702b16804SVesa Jääskeläinen 	0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2,
15802b16804SVesa Jääskeläinen 	0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3,
15902b16804SVesa Jääskeläinen 	0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe,
16002b16804SVesa Jääskeläinen 	0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50,
16102b16804SVesa Jääskeläinen 	0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a,
16202b16804SVesa Jääskeläinen 	0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3,
16302b16804SVesa Jääskeläinen 	0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35,
16402b16804SVesa Jääskeläinen 	0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
16502b16804SVesa Jääskeläinen 	0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd,
16602b16804SVesa Jääskeläinen 	0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca,
16702b16804SVesa Jääskeläinen 	0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7,
16802b16804SVesa Jääskeläinen 	0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b,
16902b16804SVesa Jääskeläinen 	0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41,
17002b16804SVesa Jääskeläinen 	0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2,
17102b16804SVesa Jääskeläinen 	0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e,
17202b16804SVesa Jääskeläinen 	0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde,
17302b16804SVesa Jääskeläinen 	0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98,
17402b16804SVesa Jääskeläinen 	0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d,
17502b16804SVesa Jääskeläinen 	0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31,
17602b16804SVesa Jääskeläinen 	0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1,
17702b16804SVesa Jääskeläinen 	0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d,
17802b16804SVesa Jääskeläinen 	0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00,
17902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
18002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
18102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
18202b16804SVesa Jääskeläinen 	0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
18302b16804SVesa Jääskeläinen 	0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
18402b16804SVesa Jääskeläinen 	0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,
18502b16804SVesa Jääskeläinen 	0x02, 0x01, 0x01,
18602b16804SVesa Jääskeläinen };
18702b16804SVesa Jääskeläinen 
18802b16804SVesa Jääskeläinen static const uint8_t secp521r1_oid_der[] = {
18902b16804SVesa Jääskeläinen 	0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30,
19002b16804SVesa Jääskeläinen 	0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
19102b16804SVesa Jääskeläinen 	0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
19202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19502b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19602b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
19902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x81,
20002b16804SVesa Jääskeläinen 	0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
20102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20502b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20602b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
20802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xfc, 0x04, 0x42, 0x00,
20902b16804SVesa Jääskeläinen 	0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
21002b16804SVesa Jääskeläinen 	0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
21102b16804SVesa Jääskeläinen 	0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
21202b16804SVesa Jääskeläinen 	0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
21302b16804SVesa Jääskeläinen 	0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
21402b16804SVesa Jääskeläinen 	0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
21502b16804SVesa Jääskeläinen 	0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
21602b16804SVesa Jääskeläinen 	0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
21702b16804SVesa Jääskeläinen 	0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00,
21802b16804SVesa Jääskeläinen 	0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
21902b16804SVesa Jääskeläinen 	0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba,
22002b16804SVesa Jääskeläinen 	0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e,
22102b16804SVesa Jääskeläinen 	0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
22202b16804SVesa Jääskeläinen 	0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64,
22302b16804SVesa Jääskeläinen 	0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28,
22402b16804SVesa Jääskeläinen 	0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
22502b16804SVesa Jääskeläinen 	0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d,
22602b16804SVesa Jääskeläinen 	0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48,
22702b16804SVesa Jääskeläinen 	0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
22802b16804SVesa Jääskeläinen 	0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18,
22902b16804SVesa Jääskeläinen 	0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
23002b16804SVesa Jääskeläinen 	0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
23102b16804SVesa Jääskeläinen 	0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
23202b16804SVesa Jääskeläinen 	0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
23302b16804SVesa Jääskeläinen 	0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
23402b16804SVesa Jääskeläinen 	0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
23502b16804SVesa Jääskeläinen 	0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
23602b16804SVesa Jääskeläinen 	0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
23702b16804SVesa Jääskeläinen 	0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
23802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
23902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
24002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
24102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, 0x87, 0x83,
24202b16804SVesa Jääskeläinen 	0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
24302b16804SVesa Jääskeläinen 	0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8,
24402b16804SVesa Jääskeläinen 	0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e,
24502b16804SVesa Jääskeläinen 	0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
24602b16804SVesa Jääskeläinen };
24702b16804SVesa Jääskeläinen 
248*03e07432SValerii Chubar /*
249*03e07432SValerii Chubar  * Edwards curves may be specified in two flavours:
250*03e07432SValerii Chubar  * - as a PrintableString 'edwards25519' or 'edwards448'
251*03e07432SValerii Chubar  * - as an OID, DER encoded ASN.1 Object
252*03e07432SValerii Chubar  */
253*03e07432SValerii Chubar 
254*03e07432SValerii Chubar static const uint8_t ed25519_name_der[] = {
255*03e07432SValerii Chubar 	0x13, 0x0c, 'e', 'd', 'w', 'a', 'r', 'd', 's',
256*03e07432SValerii Chubar 	'2', '5', '5', '1', '9',
257*03e07432SValerii Chubar };
258*03e07432SValerii Chubar 
259*03e07432SValerii Chubar static const uint8_t ed25519_oid_der[] = {
260*03e07432SValerii Chubar 	0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda,
261*03e07432SValerii Chubar 	0x47, 0x0f, 0x01,
262*03e07432SValerii Chubar };
263*03e07432SValerii Chubar 
26402b16804SVesa Jääskeläinen struct supported_ecc_curve {
26502b16804SVesa Jääskeläinen 	const uint8_t *oid_der;
26602b16804SVesa Jääskeläinen 	size_t oid_size;
26702b16804SVesa Jääskeläinen 	const uint8_t *name_der;
26802b16804SVesa Jääskeläinen 	size_t name_size;
26902b16804SVesa Jääskeläinen 	size_t key_size;
27002b16804SVesa Jääskeläinen 	uint32_t tee_id;
27102b16804SVesa Jääskeläinen 	const char *label;
27202b16804SVesa Jääskeläinen 	size_t label_size;
27302b16804SVesa Jääskeläinen };
27402b16804SVesa Jääskeläinen 
27502b16804SVesa Jääskeläinen #define ECC_CURVE(_tee_id, _key_size, _label)			\
27602b16804SVesa Jääskeläinen 	{							\
27702b16804SVesa Jääskeläinen 		.tee_id = (_tee_id),				\
27802b16804SVesa Jääskeläinen 		.key_size = (_key_size),			\
27902b16804SVesa Jääskeläinen 		.oid_der = _label ## _oid_der,			\
28002b16804SVesa Jääskeläinen 		.oid_size = sizeof(_label ## _oid_der),		\
28102b16804SVesa Jääskeläinen 		.name_der = _label ## _name_der,		\
28202b16804SVesa Jääskeläinen 		.name_size = sizeof(_label ## _name_der),	\
28302b16804SVesa Jääskeläinen 		.label = #_label,				\
28402b16804SVesa Jääskeläinen 		.label_size = sizeof(#_label) - 1,		\
28502b16804SVesa Jääskeläinen 	}
28602b16804SVesa Jääskeläinen 
28702b16804SVesa Jääskeläinen static const struct supported_ecc_curve ec_curve_param[] = {
28802b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1),
28902b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1),
29002b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1),
29102b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1),
29202b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1),
293*03e07432SValerii Chubar 	ECC_CURVE(TEE_ECC_CURVE_25519, 256, ed25519),
29402b16804SVesa Jääskeläinen };
29502b16804SVesa Jääskeläinen 
29602b16804SVesa Jääskeläinen static const struct supported_ecc_curve *get_curve(void *attr, size_t size)
29702b16804SVesa Jääskeläinen {
29802b16804SVesa Jääskeläinen 	size_t idx = 0;
29902b16804SVesa Jääskeläinen 
30002b16804SVesa Jääskeläinen 	/* Weak: not a real DER parser: try by params then by named curve */
30102b16804SVesa Jääskeläinen 	for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) {
30202b16804SVesa Jääskeläinen 		const struct supported_ecc_curve *curve = ec_curve_param + idx;
30302b16804SVesa Jääskeläinen 
30402b16804SVesa Jääskeläinen 		if (size == curve->oid_size &&
30502b16804SVesa Jääskeläinen 		    !TEE_MemCompare(attr, curve->oid_der, curve->oid_size))
30602b16804SVesa Jääskeläinen 			return curve;
30702b16804SVesa Jääskeläinen 
30802b16804SVesa Jääskeläinen 		if (size == curve->name_size &&
30902b16804SVesa Jääskeläinen 		    !TEE_MemCompare(attr, curve->name_der, curve->name_size))
31002b16804SVesa Jääskeläinen 			return curve;
31102b16804SVesa Jääskeläinen 	}
31202b16804SVesa Jääskeläinen 
31302b16804SVesa Jääskeläinen 	return NULL;
31402b16804SVesa Jääskeläinen }
31502b16804SVesa Jääskeläinen 
31602b16804SVesa Jääskeläinen size_t ec_params2tee_keysize(void *ec_params, size_t size)
31702b16804SVesa Jääskeläinen {
31802b16804SVesa Jääskeläinen 	const struct supported_ecc_curve *curve = get_curve(ec_params, size);
31902b16804SVesa Jääskeläinen 
32002b16804SVesa Jääskeläinen 	if (!curve)
32102b16804SVesa Jääskeläinen 		return 0;
32202b16804SVesa Jääskeläinen 
32302b16804SVesa Jääskeläinen 	return curve->key_size;
32402b16804SVesa Jääskeläinen }
32502b16804SVesa Jääskeläinen 
32602b16804SVesa Jääskeläinen /*
32702b16804SVesa Jääskeläinen  * This function intentionally panics if the curve is not found.
32802b16804SVesa Jääskeläinen  * Use ec_params2tee_keysize() to check the curve is supported by
32902b16804SVesa Jääskeläinen  * the internal core API.
33002b16804SVesa Jääskeläinen  */
33102b16804SVesa Jääskeläinen uint32_t ec_params2tee_curve(void *ec_params, size_t size)
33202b16804SVesa Jääskeläinen {
33302b16804SVesa Jääskeläinen 	const struct supported_ecc_curve *curve = get_curve(ec_params, size);
33402b16804SVesa Jääskeläinen 
33502b16804SVesa Jääskeläinen 	assert(curve);
33602b16804SVesa Jääskeläinen 
33702b16804SVesa Jääskeläinen 	return curve->tee_id;
33802b16804SVesa Jääskeläinen }
33902b16804SVesa Jääskeläinen 
340fb279d8bSVesa Jääskeläinen enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs,
341fb279d8bSVesa Jääskeläinen 				     size_t *tee_count,
342fb279d8bSVesa Jääskeläinen 				     struct pkcs11_object *obj)
343fb279d8bSVesa Jääskeläinen {
344fb279d8bSVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
345fb279d8bSVesa Jääskeläinen 	size_t count = 0;
346fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
347fb279d8bSVesa Jääskeläinen 
348fb279d8bSVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC);
349fb279d8bSVesa Jääskeläinen 
350fb279d8bSVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
351fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
352fb279d8bSVesa Jääskeläinen 		attrs = TEE_Malloc(3 * sizeof(TEE_Attribute),
353fb279d8bSVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
354fb279d8bSVesa Jääskeläinen 		if (!attrs)
355fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
356fb279d8bSVesa Jääskeläinen 
357fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
358fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_PARAMS))
359fb279d8bSVesa Jääskeläinen 			count++;
360fb279d8bSVesa Jääskeläinen 
361fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
362fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
363fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
364fb279d8bSVesa Jääskeläinen 			count++;
365fb279d8bSVesa Jääskeläinen 
366fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
367fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
368fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
369fb279d8bSVesa Jääskeläinen 			count++;
370fb279d8bSVesa Jääskeläinen 
371fb279d8bSVesa Jääskeläinen 		if (count == 3)
372fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
373fb279d8bSVesa Jääskeläinen 
374fb279d8bSVesa Jääskeläinen 		break;
375fb279d8bSVesa Jääskeläinen 
376fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
377fb279d8bSVesa Jääskeläinen 		attrs = TEE_Malloc(4 * sizeof(TEE_Attribute),
378fb279d8bSVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
379fb279d8bSVesa Jääskeläinen 		if (!attrs)
380fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
381fb279d8bSVesa Jääskeläinen 
382fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
383fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_PARAMS))
384fb279d8bSVesa Jääskeläinen 			count++;
385fb279d8bSVesa Jääskeläinen 
386fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
387fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PRIVATE_VALUE,
388fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_VALUE))
389fb279d8bSVesa Jääskeläinen 			count++;
390fb279d8bSVesa Jääskeläinen 
391fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
392fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
393fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
394fb279d8bSVesa Jääskeläinen 			count++;
395fb279d8bSVesa Jääskeläinen 
396fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
397fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
398fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
399fb279d8bSVesa Jääskeläinen 			count++;
400fb279d8bSVesa Jääskeläinen 
401fb279d8bSVesa Jääskeläinen 		if (count == 4)
402fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
403fb279d8bSVesa Jääskeläinen 
404fb279d8bSVesa Jääskeläinen 		break;
405fb279d8bSVesa Jääskeläinen 
406fb279d8bSVesa Jääskeläinen 	default:
407fb279d8bSVesa Jääskeläinen 		assert(0);
408fb279d8bSVesa Jääskeläinen 		break;
409fb279d8bSVesa Jääskeläinen 	}
410fb279d8bSVesa Jääskeläinen 
411fb279d8bSVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
412fb279d8bSVesa Jääskeläinen 		*tee_attrs = attrs;
413fb279d8bSVesa Jääskeläinen 		*tee_count = count;
414fb279d8bSVesa Jääskeläinen 	} else {
415fb279d8bSVesa Jääskeläinen 		TEE_Free(attrs);
416fb279d8bSVesa Jääskeläinen 	}
417fb279d8bSVesa Jääskeläinen 
418fb279d8bSVesa Jääskeläinen 	return rc;
419fb279d8bSVesa Jääskeläinen }
420fb279d8bSVesa Jääskeläinen 
421fb279d8bSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
422fb279d8bSVesa Jääskeläinen 				   struct pkcs11_attribute_head *proc_params,
423fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj)
424fb279d8bSVesa Jääskeläinen {
425fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
426fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
427fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
428fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
429fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
430fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
431fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
432fb279d8bSVesa Jääskeläinen 		break;
433fb279d8bSVesa Jääskeläinen 	default:
434fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
435fb279d8bSVesa Jääskeläinen 	}
436fb279d8bSVesa Jääskeläinen 
437fb279d8bSVesa Jääskeläinen 	/*
438fb279d8bSVesa Jääskeläinen 	 * TODO: Fixing this in a way to support also other EC curves would
439fb279d8bSVesa Jääskeläinen 	 * require OP-TEE to be updated for newer version of GlobalPlatform API
440fb279d8bSVesa Jääskeläinen 	 */
441fb279d8bSVesa Jääskeläinen 	switch (get_object_key_bit_size(obj)) {
442fb279d8bSVesa Jääskeläinen 	case 192:
443fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P192;
444fb279d8bSVesa Jääskeläinen 		break;
445fb279d8bSVesa Jääskeläinen 	case 224:
446fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P224;
447fb279d8bSVesa Jääskeläinen 		break;
448fb279d8bSVesa Jääskeläinen 	case 256:
449fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P256;
450fb279d8bSVesa Jääskeläinen 		break;
451fb279d8bSVesa Jääskeläinen 	case 384:
452fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P384;
453fb279d8bSVesa Jääskeläinen 		break;
454fb279d8bSVesa Jääskeläinen 	case 521:
455fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P521;
456fb279d8bSVesa Jääskeläinen 		break;
457fb279d8bSVesa Jääskeläinen 	default:
458fb279d8bSVesa Jääskeläinen 		TEE_Panic(0);
459fb279d8bSVesa Jääskeläinen 		break;
460fb279d8bSVesa Jääskeläinen 	}
461fb279d8bSVesa Jääskeläinen 
462fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
463fb279d8bSVesa Jääskeläinen }
464fb279d8bSVesa Jääskeläinen 
46502b16804SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
46602b16804SVesa Jääskeläinen 					     struct obj_attrs **priv_head,
46702b16804SVesa Jääskeläinen 					     TEE_ObjectHandle tee_obj,
46802b16804SVesa Jääskeläinen 					     size_t tee_size)
46902b16804SVesa Jääskeläinen {
47002b16804SVesa Jääskeläinen 	void *x_ptr = NULL;
47102b16804SVesa Jääskeläinen 	void *y_ptr = NULL;
47202b16804SVesa Jääskeläinen 	uint8_t *ecpoint = NULL;
47302b16804SVesa Jääskeläinen 	size_t x_size = 0;
47402b16804SVesa Jääskeläinen 	size_t y_size = 0;
47502b16804SVesa Jääskeläinen 	size_t psize = 0;
47602b16804SVesa Jääskeläinen 	size_t qsize = 0;
47702b16804SVesa Jääskeläinen 	size_t dersize = 0;
47802b16804SVesa Jääskeläinen 	size_t poffset = 0;
47902b16804SVesa Jääskeläinen 	size_t hsize = 0;
48002b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
48102b16804SVesa Jääskeläinen 
48202b16804SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
48302b16804SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
48402b16804SVesa Jääskeläinen 	if (rc)
48502b16804SVesa Jääskeläinen 		goto out;
48602b16804SVesa Jääskeläinen 
48702b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
48802b16804SVesa Jääskeläinen 					  &x_ptr, &x_size);
48902b16804SVesa Jääskeläinen 	if (rc)
49002b16804SVesa Jääskeläinen 		goto out;
49102b16804SVesa Jääskeläinen 
49202b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
49302b16804SVesa Jääskeläinen 					  &y_ptr, &y_size);
49402b16804SVesa Jääskeläinen 	if (rc)
49502b16804SVesa Jääskeläinen 		goto x_cleanup;
49602b16804SVesa Jääskeläinen 
49702b16804SVesa Jääskeläinen 	psize = (tee_size + 7) / 8;
49802b16804SVesa Jääskeläinen 	if (x_size > psize || y_size > psize) {
49902b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_ARGUMENTS_BAD;
50002b16804SVesa Jääskeläinen 		goto y_cleanup;
50102b16804SVesa Jääskeläinen 	}
50202b16804SVesa Jääskeläinen 
50302b16804SVesa Jääskeläinen 	qsize = 1 + 2 * psize;
50402b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
50502b16804SVesa Jääskeläinen 		/* DER short definitive form up to 127 bytes */
50602b16804SVesa Jääskeläinen 		dersize = qsize + 2;
50702b16804SVesa Jääskeläinen 		hsize = 2 /* der */ + 1 /* point compression */;
50802b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
50902b16804SVesa Jääskeläinen 		/* DER long definitive form up to 255 bytes */
51002b16804SVesa Jääskeläinen 		dersize = qsize + 3;
51102b16804SVesa Jääskeläinen 		hsize = 3 /* der */ + 1 /* point compression */;
51202b16804SVesa Jääskeläinen 	} else {
51302b16804SVesa Jääskeläinen 		EMSG("Too long DER value");
51402b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
51502b16804SVesa Jääskeläinen 		goto y_cleanup;
51602b16804SVesa Jääskeläinen 	}
51702b16804SVesa Jääskeläinen 
51802b16804SVesa Jääskeläinen 	ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
51902b16804SVesa Jääskeläinen 	if (!ecpoint) {
52002b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_DEVICE_MEMORY;
52102b16804SVesa Jääskeläinen 		goto y_cleanup;
52202b16804SVesa Jääskeläinen 	}
52302b16804SVesa Jääskeläinen 
52402b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
52502b16804SVesa Jääskeläinen 		/* DER encoding */
52602b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
52702b16804SVesa Jääskeläinen 		ecpoint[1] = qsize & 0x7f;
52802b16804SVesa Jääskeläinen 
52902b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
53002b16804SVesa Jääskeläinen 		ecpoint[2] = 0x04;
53102b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
53202b16804SVesa Jääskeläinen 		/* DER encoding */
53302b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
53402b16804SVesa Jääskeläinen 		ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
53502b16804SVesa Jääskeläinen 		ecpoint[2] = qsize & 0xFF;
53602b16804SVesa Jääskeläinen 
53702b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
53802b16804SVesa Jääskeläinen 		ecpoint[3] = 0x04;
53902b16804SVesa Jääskeläinen 	}
54002b16804SVesa Jääskeläinen 
54102b16804SVesa Jääskeläinen 	poffset = 0;
54202b16804SVesa Jääskeläinen 	if (x_size < psize)
54302b16804SVesa Jääskeläinen 		poffset = psize - x_size;
54402b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
54502b16804SVesa Jääskeläinen 
54602b16804SVesa Jääskeläinen 	poffset = 0;
54702b16804SVesa Jääskeläinen 	if (y_size < psize)
54802b16804SVesa Jääskeläinen 		poffset = psize - y_size;
54902b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
55002b16804SVesa Jääskeläinen 
55102b16804SVesa Jääskeläinen 	/*
55202b16804SVesa Jääskeläinen 	 * Add EC_POINT on both private and public key objects as
55302b16804SVesa Jääskeläinen 	 * TEE_PopulateTransientObject requires public x/y values
55402b16804SVesa Jääskeläinen 	 * for TEE_TYPE_ECDSA_KEYPAIR.
55502b16804SVesa Jääskeläinen 	 */
55602b16804SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
55702b16804SVesa Jääskeläinen 	if (rc)
55802b16804SVesa Jääskeläinen 		goto ecpoint_cleanup;
55902b16804SVesa Jääskeläinen 
56002b16804SVesa Jääskeläinen 	rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
56102b16804SVesa Jääskeläinen 
56202b16804SVesa Jääskeläinen ecpoint_cleanup:
56302b16804SVesa Jääskeläinen 	TEE_Free(ecpoint);
56402b16804SVesa Jääskeläinen y_cleanup:
56502b16804SVesa Jääskeläinen 	TEE_Free(y_ptr);
56602b16804SVesa Jääskeläinen x_cleanup:
56702b16804SVesa Jääskeläinen 	TEE_Free(x_ptr);
56802b16804SVesa Jääskeläinen out:
56902b16804SVesa Jääskeläinen 	return rc;
57002b16804SVesa Jääskeläinen }
57102b16804SVesa Jääskeläinen 
57202b16804SVesa Jääskeläinen enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
57302b16804SVesa Jääskeläinen 				struct obj_attrs **pub_head,
57402b16804SVesa Jääskeläinen 				struct obj_attrs **priv_head)
57502b16804SVesa Jääskeläinen {
57602b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
57702b16804SVesa Jääskeläinen 	void *a_ptr = NULL;
57802b16804SVesa Jääskeläinen 	uint32_t a_size = 0;
57902b16804SVesa Jääskeläinen 	uint32_t tee_size = 0;
58002b16804SVesa Jääskeläinen 	uint32_t tee_curve = 0;
58102b16804SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
58202b16804SVesa Jääskeläinen 	TEE_Attribute tee_key_attr[1] = { };
58302b16804SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
58402b16804SVesa Jääskeläinen 
58502b16804SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
58602b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
58702b16804SVesa Jääskeläinen 
58802b16804SVesa Jääskeläinen 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
58902b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
59002b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
59102b16804SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
59202b16804SVesa Jääskeläinen 		trace_attributes("public-key", *pub_head);
59302b16804SVesa Jääskeläinen 		trace_attributes("private-key", *priv_head);
59402b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
59502b16804SVesa Jääskeläinen 	}
59602b16804SVesa Jääskeläinen 
59702b16804SVesa Jääskeläinen 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
59802b16804SVesa Jääskeläinen 			      &a_ptr, &a_size) || !a_ptr) {
59902b16804SVesa Jääskeläinen 		EMSG("No EC_PARAMS attribute found in public key");
60002b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
60102b16804SVesa Jääskeläinen 	}
60202b16804SVesa Jääskeläinen 
60302b16804SVesa Jääskeläinen 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
60402b16804SVesa Jääskeläinen 	if (!tee_size)
60502b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
60602b16804SVesa Jääskeläinen 
60702b16804SVesa Jääskeläinen 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
60802b16804SVesa Jääskeläinen 
60902b16804SVesa Jääskeläinen 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
61002b16804SVesa Jääskeläinen 
61102b16804SVesa Jääskeläinen 	/* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
61202b16804SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
61302b16804SVesa Jääskeläinen 					  &tee_obj);
61402b16804SVesa Jääskeläinen 	if (res) {
61502b16804SVesa Jääskeläinen 		EMSG("Transient alloc failed with %#"PRIx32, res);
61602b16804SVesa Jääskeläinen 		return tee2pkcs_error(res);
61702b16804SVesa Jääskeläinen 	}
61802b16804SVesa Jääskeläinen 
61902b16804SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
62002b16804SVesa Jääskeläinen 	if (res) {
62102b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
62202b16804SVesa Jääskeläinen 		goto out;
62302b16804SVesa Jääskeläinen 	}
62402b16804SVesa Jääskeläinen 
62502b16804SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
62602b16804SVesa Jääskeläinen 	if (res) {
62702b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
62802b16804SVesa Jääskeläinen 		goto out;
62902b16804SVesa Jääskeläinen 	}
63002b16804SVesa Jääskeläinen 
63102b16804SVesa Jääskeläinen 	/* Private key needs the same EC_PARAMS as used by the public key */
63202b16804SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
63302b16804SVesa Jääskeläinen 	if (rc)
63402b16804SVesa Jääskeläinen 		goto out;
63502b16804SVesa Jääskeläinen 
63602b16804SVesa Jääskeläinen 	rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
63702b16804SVesa Jääskeläinen 
63802b16804SVesa Jääskeläinen out:
63902b16804SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
64002b16804SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
64102b16804SVesa Jääskeläinen 
64202b16804SVesa Jääskeläinen 	return rc;
64302b16804SVesa Jääskeläinen }
644fb279d8bSVesa Jääskeläinen 
645*03e07432SValerii Chubar enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs,
646*03e07432SValerii Chubar 					size_t *tee_count,
647*03e07432SValerii Chubar 					struct pkcs11_object *obj)
648*03e07432SValerii Chubar {
649*03e07432SValerii Chubar 	TEE_Attribute *attrs = NULL;
650*03e07432SValerii Chubar 	size_t count = 0;
651*03e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
652*03e07432SValerii Chubar 
653*03e07432SValerii Chubar 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS);
654*03e07432SValerii Chubar 
655*03e07432SValerii Chubar 	switch (get_class(obj->attributes)) {
656*03e07432SValerii Chubar 	case PKCS11_CKO_PUBLIC_KEY:
657*03e07432SValerii Chubar 		attrs = TEE_Malloc(sizeof(TEE_Attribute),
658*03e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
659*03e07432SValerii Chubar 		if (!attrs)
660*03e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
661*03e07432SValerii Chubar 
662*03e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
663*03e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
664*03e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
665*03e07432SValerii Chubar 			count++;
666*03e07432SValerii Chubar 
667*03e07432SValerii Chubar 		if (count == 1)
668*03e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
669*03e07432SValerii Chubar 
670*03e07432SValerii Chubar 		break;
671*03e07432SValerii Chubar 
672*03e07432SValerii Chubar 	case PKCS11_CKO_PRIVATE_KEY:
673*03e07432SValerii Chubar 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
674*03e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
675*03e07432SValerii Chubar 		if (!attrs)
676*03e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
677*03e07432SValerii Chubar 
678*03e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
679*03e07432SValerii Chubar 				       TEE_ATTR_ED25519_PRIVATE_VALUE,
680*03e07432SValerii Chubar 				       obj, PKCS11_CKA_VALUE))
681*03e07432SValerii Chubar 			count++;
682*03e07432SValerii Chubar 
683*03e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
684*03e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
685*03e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
686*03e07432SValerii Chubar 			count++;
687*03e07432SValerii Chubar 
688*03e07432SValerii Chubar 		if (count == 2)
689*03e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
690*03e07432SValerii Chubar 
691*03e07432SValerii Chubar 		break;
692*03e07432SValerii Chubar 
693*03e07432SValerii Chubar 	default:
694*03e07432SValerii Chubar 		assert(0);
695*03e07432SValerii Chubar 		break;
696*03e07432SValerii Chubar 	}
697*03e07432SValerii Chubar 
698*03e07432SValerii Chubar 	if (rc == PKCS11_CKR_OK) {
699*03e07432SValerii Chubar 		*tee_attrs = attrs;
700*03e07432SValerii Chubar 		*tee_count = count;
701*03e07432SValerii Chubar 	} else {
702*03e07432SValerii Chubar 		TEE_Free(attrs);
703*03e07432SValerii Chubar 	}
704*03e07432SValerii Chubar 
705*03e07432SValerii Chubar 	return rc;
706*03e07432SValerii Chubar }
707*03e07432SValerii Chubar 
708*03e07432SValerii Chubar enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params,
709*03e07432SValerii Chubar 				   struct obj_attrs **pub_head,
710*03e07432SValerii Chubar 				   struct obj_attrs **priv_head)
711*03e07432SValerii Chubar {
712*03e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
713*03e07432SValerii Chubar 	void *a_ptr = NULL;
714*03e07432SValerii Chubar 	uint32_t a_size = 0;
715*03e07432SValerii Chubar 	uint32_t tee_size = 0;
716*03e07432SValerii Chubar 	uint32_t tee_curve = 0;
717*03e07432SValerii Chubar 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
718*03e07432SValerii Chubar 	TEE_Attribute tee_key_attr[1] = { };
719*03e07432SValerii Chubar 	TEE_Result res = TEE_ERROR_GENERIC;
720*03e07432SValerii Chubar 
721*03e07432SValerii Chubar 	if (!proc_params || !*pub_head || !*priv_head)
722*03e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
723*03e07432SValerii Chubar 
724*03e07432SValerii Chubar 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
725*03e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
726*03e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
727*03e07432SValerii Chubar 		EMSG("Unexpected attribute(s) found");
728*03e07432SValerii Chubar 		trace_attributes("public-key", *pub_head);
729*03e07432SValerii Chubar 		trace_attributes("private-key", *priv_head);
730*03e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
731*03e07432SValerii Chubar 	}
732*03e07432SValerii Chubar 
733*03e07432SValerii Chubar 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
734*03e07432SValerii Chubar 			      &a_ptr, &a_size) || !a_ptr) {
735*03e07432SValerii Chubar 		EMSG("No EC_PARAMS attribute found in public key");
736*03e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
737*03e07432SValerii Chubar 	}
738*03e07432SValerii Chubar 
739*03e07432SValerii Chubar 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
740*03e07432SValerii Chubar 	if (!tee_size)
741*03e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
742*03e07432SValerii Chubar 
743*03e07432SValerii Chubar 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
744*03e07432SValerii Chubar 
745*03e07432SValerii Chubar 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 1);
746*03e07432SValerii Chubar 
747*03e07432SValerii Chubar 	res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
748*03e07432SValerii Chubar 					  &tee_obj);
749*03e07432SValerii Chubar 	if (res) {
750*03e07432SValerii Chubar 		EMSG("Transient alloc failed with %#"PRIx32, res);
751*03e07432SValerii Chubar 		return tee2pkcs_error(res);
752*03e07432SValerii Chubar 	}
753*03e07432SValerii Chubar 
754*03e07432SValerii Chubar 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
755*03e07432SValerii Chubar 	if (res) {
756*03e07432SValerii Chubar 		rc = tee2pkcs_error(res);
757*03e07432SValerii Chubar 		goto out;
758*03e07432SValerii Chubar 	}
759*03e07432SValerii Chubar 
760*03e07432SValerii Chubar 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
761*03e07432SValerii Chubar 	if (res) {
762*03e07432SValerii Chubar 		rc = tee2pkcs_error(res);
763*03e07432SValerii Chubar 		goto out;
764*03e07432SValerii Chubar 	}
765*03e07432SValerii Chubar 
766*03e07432SValerii Chubar 	/* Private key needs the same EC_PARAMS as used by the public key */
767*03e07432SValerii Chubar 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
768*03e07432SValerii Chubar 	if (rc)
769*03e07432SValerii Chubar 		goto out;
770*03e07432SValerii Chubar 
771*03e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
772*03e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
773*03e07432SValerii Chubar 	if (rc)
774*03e07432SValerii Chubar 		goto out;
775*03e07432SValerii Chubar 
776*03e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
777*03e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
778*03e07432SValerii Chubar 	if (rc)
779*03e07432SValerii Chubar 		goto out;
780*03e07432SValerii Chubar 
781*03e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
782*03e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
783*03e07432SValerii Chubar 
784*03e07432SValerii Chubar out:
785*03e07432SValerii Chubar 	if (tee_obj != TEE_HANDLE_NULL)
786*03e07432SValerii Chubar 		TEE_CloseObject(tee_obj);
787*03e07432SValerii Chubar 
788*03e07432SValerii Chubar 	return rc;
789*03e07432SValerii Chubar }
790*03e07432SValerii Chubar 
791*03e07432SValerii Chubar enum pkcs11_rc
792*03e07432SValerii Chubar pkcs2tee_proc_params_eddsa(struct active_processing *proc,
793*03e07432SValerii Chubar 			   struct pkcs11_attribute_head *proc_params)
794*03e07432SValerii Chubar {
795*03e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
796*03e07432SValerii Chubar 	uint32_t ctx_len = 0;
797*03e07432SValerii Chubar 	uint32_t flag = 0;
798*03e07432SValerii Chubar 	void *ctx_data = NULL;
799*03e07432SValerii Chubar 	struct serialargs args = { };
800*03e07432SValerii Chubar 	struct eddsa_processing_ctx *ctx = NULL;
801*03e07432SValerii Chubar 
802*03e07432SValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
803*03e07432SValerii Chubar 
804*03e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &flag);
805*03e07432SValerii Chubar 	if (rc)
806*03e07432SValerii Chubar 		return rc;
807*03e07432SValerii Chubar 
808*03e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &ctx_len);
809*03e07432SValerii Chubar 	if (rc)
810*03e07432SValerii Chubar 		return rc;
811*03e07432SValerii Chubar 
812*03e07432SValerii Chubar 	rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
813*03e07432SValerii Chubar 	if (rc)
814*03e07432SValerii Chubar 		return rc;
815*03e07432SValerii Chubar 
816*03e07432SValerii Chubar 	if (serialargs_remaining_bytes(&args))
817*03e07432SValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
818*03e07432SValerii Chubar 
819*03e07432SValerii Chubar 	proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
820*03e07432SValerii Chubar 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
821*03e07432SValerii Chubar 	if (!proc->extra_ctx)
822*03e07432SValerii Chubar 		return PKCS11_CKR_DEVICE_MEMORY;
823*03e07432SValerii Chubar 
824*03e07432SValerii Chubar 	ctx = proc->extra_ctx;
825*03e07432SValerii Chubar 	ctx->ctx_len = ctx_len;
826*03e07432SValerii Chubar 	ctx->flag = flag;
827*03e07432SValerii Chubar 	TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
828*03e07432SValerii Chubar 
829*03e07432SValerii Chubar 	return PKCS11_CKR_OK;
830*03e07432SValerii Chubar }
831*03e07432SValerii Chubar 
832fb279d8bSVesa Jääskeläinen size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
833fb279d8bSVesa Jääskeläinen {
834fb279d8bSVesa Jääskeläinen 	TEE_OperationInfo info = { };
835fb279d8bSVesa Jääskeläinen 
836fb279d8bSVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
837fb279d8bSVesa Jääskeläinen 
838fb279d8bSVesa Jääskeläinen 	switch (info.algorithm) {
839fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P192:
840fb279d8bSVesa Jääskeläinen 		return 24;
841fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P224:
842fb279d8bSVesa Jääskeläinen 		return 28;
843fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P256:
844fb279d8bSVesa Jääskeläinen 		return 32;
845fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P384:
846fb279d8bSVesa Jääskeläinen 		return 48;
847fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P521:
848fb279d8bSVesa Jääskeläinen 		return 66;
849fb279d8bSVesa Jääskeläinen 	default:
850fb279d8bSVesa Jääskeläinen 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
851fb279d8bSVesa Jääskeläinen 		return 0;
852fb279d8bSVesa Jääskeläinen 	}
853fb279d8bSVesa Jääskeläinen }
854cc062b46SJorge Ramirez-Ortiz 
855cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
856cc062b46SJorge Ramirez-Ortiz 				   void **pub_data, size_t *pub_size)
857cc062b46SJorge Ramirez-Ortiz {
858cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
859cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
860cc062b46SJorge Ramirez-Ortiz 	uint32_t word = 0;
861cc062b46SJorge Ramirez-Ortiz 	uint8_t byte = 0;
862cc062b46SJorge Ramirez-Ortiz 
863cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
864cc062b46SJorge Ramirez-Ortiz 
865cc062b46SJorge Ramirez-Ortiz 	/* Skip KDF */
866cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
867cc062b46SJorge Ramirez-Ortiz 	if (rc)
868cc062b46SJorge Ramirez-Ortiz 		return rc;
869cc062b46SJorge Ramirez-Ortiz 
870cc062b46SJorge Ramirez-Ortiz 	/* Shared data size, shall be 0 */
871cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
872cc062b46SJorge Ramirez-Ortiz 	if (rc || word)
873cc062b46SJorge Ramirez-Ortiz 		return rc;
874cc062b46SJorge Ramirez-Ortiz 
875cc062b46SJorge Ramirez-Ortiz 	/* Public data size and content */
876cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
877cc062b46SJorge Ramirez-Ortiz 	if (rc || !word)
878cc062b46SJorge Ramirez-Ortiz 		return rc;
879cc062b46SJorge Ramirez-Ortiz 
880cc062b46SJorge Ramirez-Ortiz 	*pub_size = word;
881cc062b46SJorge Ramirez-Ortiz 
882cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
883cc062b46SJorge Ramirez-Ortiz 	if (rc)
884cc062b46SJorge Ramirez-Ortiz 		return rc;
885cc062b46SJorge Ramirez-Ortiz 
886cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
887cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
888cc062b46SJorge Ramirez-Ortiz 
889cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x04) {
890cc062b46SJorge Ramirez-Ortiz 		EMSG("DER compressed public key format not yet supported");
891cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
892cc062b46SJorge Ramirez-Ortiz 	}
893cc062b46SJorge Ramirez-Ortiz 
894cc062b46SJorge Ramirez-Ortiz 	*pub_size -= sizeof(uint8_t);
895cc062b46SJorge Ramirez-Ortiz 
896cc062b46SJorge Ramirez-Ortiz 	if (*pub_size >= 0x80) {
897cc062b46SJorge Ramirez-Ortiz 		EMSG("DER long definitive form not yet supported");
898cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
899cc062b46SJorge Ramirez-Ortiz 	}
900cc062b46SJorge Ramirez-Ortiz 
901cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
902cc062b46SJorge Ramirez-Ortiz 	if (rc)
903cc062b46SJorge Ramirez-Ortiz 		return rc;
904cc062b46SJorge Ramirez-Ortiz 
905cc062b46SJorge Ramirez-Ortiz 	if (serialargs_remaining_bytes(&args))
906cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
907cc062b46SJorge Ramirez-Ortiz 
908cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
909cc062b46SJorge Ramirez-Ortiz }
910cc062b46SJorge Ramirez-Ortiz 
911cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
912cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_attribute_head *proc_params,
913cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_object *obj)
914cc062b46SJorge Ramirez-Ortiz {
915cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
916cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
917cc062b46SJorge Ramirez-Ortiz 	uint32_t kdf = 0;
918cc062b46SJorge Ramirez-Ortiz 
919cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
920cc062b46SJorge Ramirez-Ortiz 
921cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &kdf);
922cc062b46SJorge Ramirez-Ortiz 	if (rc)
923cc062b46SJorge Ramirez-Ortiz 		return rc;
924cc062b46SJorge Ramirez-Ortiz 
925cc062b46SJorge Ramirez-Ortiz 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
926cc062b46SJorge Ramirez-Ortiz 	if (kdf != PKCS11_CKD_NULL) {
927cc062b46SJorge Ramirez-Ortiz 		DMSG("Only support CKD_NULL key derivation for ECDH");
928cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
929cc062b46SJorge Ramirez-Ortiz 	}
930cc062b46SJorge Ramirez-Ortiz 
931cc062b46SJorge Ramirez-Ortiz 	switch (get_object_key_bit_size(obj)) {
932cc062b46SJorge Ramirez-Ortiz 	case 192:
933cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P192;
934cc062b46SJorge Ramirez-Ortiz 		break;
935cc062b46SJorge Ramirez-Ortiz 	case 224:
936cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P224;
937cc062b46SJorge Ramirez-Ortiz 		break;
938cc062b46SJorge Ramirez-Ortiz 	case 256:
939cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P256;
940cc062b46SJorge Ramirez-Ortiz 		break;
941cc062b46SJorge Ramirez-Ortiz 	case 384:
942cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P384;
943cc062b46SJorge Ramirez-Ortiz 		break;
944cc062b46SJorge Ramirez-Ortiz 	case 521:
945cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P521;
946cc062b46SJorge Ramirez-Ortiz 		break;
947cc062b46SJorge Ramirez-Ortiz 	default:
948cc062b46SJorge Ramirez-Ortiz 		TEE_Panic(0);
949cc062b46SJorge Ramirez-Ortiz 		break;
950cc062b46SJorge Ramirez-Ortiz 	}
951cc062b46SJorge Ramirez-Ortiz 
952cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
953cc062b46SJorge Ramirez-Ortiz }
954