xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision ecd7f426fb4f7b5f15cab37fe20df8c76ededcc4)
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"
1503e07432SValerii 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 
24803e07432SValerii Chubar /*
24903e07432SValerii Chubar  * Edwards curves may be specified in two flavours:
25003e07432SValerii Chubar  * - as a PrintableString 'edwards25519' or 'edwards448'
25103e07432SValerii Chubar  * - as an OID, DER encoded ASN.1 Object
25203e07432SValerii Chubar  */
25303e07432SValerii Chubar 
25403e07432SValerii Chubar static const uint8_t ed25519_name_der[] = {
25503e07432SValerii Chubar 	0x13, 0x0c, 'e', 'd', 'w', 'a', 'r', 'd', 's',
25603e07432SValerii Chubar 	'2', '5', '5', '1', '9',
25703e07432SValerii Chubar };
25803e07432SValerii Chubar 
25903e07432SValerii Chubar static const uint8_t ed25519_oid_der[] = {
26003e07432SValerii Chubar 	0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda,
26103e07432SValerii Chubar 	0x47, 0x0f, 0x01,
26203e07432SValerii Chubar };
26303e07432SValerii 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),
29303e07432SValerii 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 
64503e07432SValerii Chubar enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs,
64603e07432SValerii Chubar 					size_t *tee_count,
64703e07432SValerii Chubar 					struct pkcs11_object *obj)
64803e07432SValerii Chubar {
64903e07432SValerii Chubar 	TEE_Attribute *attrs = NULL;
65003e07432SValerii Chubar 	size_t count = 0;
65103e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
65203e07432SValerii Chubar 
65303e07432SValerii Chubar 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS);
65403e07432SValerii Chubar 
65503e07432SValerii Chubar 	switch (get_class(obj->attributes)) {
65603e07432SValerii Chubar 	case PKCS11_CKO_PUBLIC_KEY:
65703e07432SValerii Chubar 		attrs = TEE_Malloc(sizeof(TEE_Attribute),
65803e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
65903e07432SValerii Chubar 		if (!attrs)
66003e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
66103e07432SValerii Chubar 
66203e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
66303e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
66403e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
66503e07432SValerii Chubar 			count++;
66603e07432SValerii Chubar 
66703e07432SValerii Chubar 		if (count == 1)
66803e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
66903e07432SValerii Chubar 
67003e07432SValerii Chubar 		break;
67103e07432SValerii Chubar 
67203e07432SValerii Chubar 	case PKCS11_CKO_PRIVATE_KEY:
67303e07432SValerii Chubar 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
67403e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
67503e07432SValerii Chubar 		if (!attrs)
67603e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
67703e07432SValerii Chubar 
67803e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
67903e07432SValerii Chubar 				       TEE_ATTR_ED25519_PRIVATE_VALUE,
68003e07432SValerii Chubar 				       obj, PKCS11_CKA_VALUE))
68103e07432SValerii Chubar 			count++;
68203e07432SValerii Chubar 
68303e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
68403e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
68503e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
68603e07432SValerii Chubar 			count++;
68703e07432SValerii Chubar 
68803e07432SValerii Chubar 		if (count == 2)
68903e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
69003e07432SValerii Chubar 
69103e07432SValerii Chubar 		break;
69203e07432SValerii Chubar 
69303e07432SValerii Chubar 	default:
69403e07432SValerii Chubar 		assert(0);
69503e07432SValerii Chubar 		break;
69603e07432SValerii Chubar 	}
69703e07432SValerii Chubar 
69803e07432SValerii Chubar 	if (rc == PKCS11_CKR_OK) {
69903e07432SValerii Chubar 		*tee_attrs = attrs;
70003e07432SValerii Chubar 		*tee_count = count;
70103e07432SValerii Chubar 	} else {
70203e07432SValerii Chubar 		TEE_Free(attrs);
70303e07432SValerii Chubar 	}
70403e07432SValerii Chubar 
70503e07432SValerii Chubar 	return rc;
70603e07432SValerii Chubar }
70703e07432SValerii Chubar 
70803e07432SValerii Chubar enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params,
70903e07432SValerii Chubar 				   struct obj_attrs **pub_head,
71003e07432SValerii Chubar 				   struct obj_attrs **priv_head)
71103e07432SValerii Chubar {
71203e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
71303e07432SValerii Chubar 	void *a_ptr = NULL;
71403e07432SValerii Chubar 	uint32_t a_size = 0;
71503e07432SValerii Chubar 	uint32_t tee_size = 0;
71603e07432SValerii Chubar 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
71703e07432SValerii Chubar 	TEE_Result res = TEE_ERROR_GENERIC;
71803e07432SValerii Chubar 
71903e07432SValerii Chubar 	if (!proc_params || !*pub_head || !*priv_head)
72003e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
72103e07432SValerii Chubar 
72203e07432SValerii Chubar 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
72303e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
724*ecd7f426SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_POINT) ||
72503e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
72603e07432SValerii Chubar 		EMSG("Unexpected attribute(s) found");
72703e07432SValerii Chubar 		trace_attributes("public-key", *pub_head);
72803e07432SValerii Chubar 		trace_attributes("private-key", *priv_head);
72903e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
73003e07432SValerii Chubar 	}
73103e07432SValerii Chubar 
73203e07432SValerii Chubar 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
73303e07432SValerii Chubar 			      &a_ptr, &a_size) || !a_ptr) {
73403e07432SValerii Chubar 		EMSG("No EC_PARAMS attribute found in public key");
73503e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
73603e07432SValerii Chubar 	}
73703e07432SValerii Chubar 
73803e07432SValerii Chubar 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
73903e07432SValerii Chubar 	if (!tee_size)
74003e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
74103e07432SValerii Chubar 
74203e07432SValerii Chubar 	res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
74303e07432SValerii Chubar 					  &tee_obj);
74403e07432SValerii Chubar 	if (res) {
74503e07432SValerii Chubar 		EMSG("Transient alloc failed with %#"PRIx32, res);
74603e07432SValerii Chubar 		return tee2pkcs_error(res);
74703e07432SValerii Chubar 	}
74803e07432SValerii Chubar 
74903e07432SValerii Chubar 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
75003e07432SValerii Chubar 	if (res) {
75103e07432SValerii Chubar 		rc = tee2pkcs_error(res);
75203e07432SValerii Chubar 		goto out;
75303e07432SValerii Chubar 	}
75403e07432SValerii Chubar 
755*ecd7f426SValerii Chubar 	res = TEE_GenerateKey(tee_obj, tee_size, NULL, 0);
75603e07432SValerii Chubar 	if (res) {
75703e07432SValerii Chubar 		rc = tee2pkcs_error(res);
75803e07432SValerii Chubar 		goto out;
75903e07432SValerii Chubar 	}
76003e07432SValerii Chubar 
76103e07432SValerii Chubar 	/* Private key needs the same EC_PARAMS as used by the public key */
76203e07432SValerii Chubar 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
76303e07432SValerii Chubar 	if (rc)
76403e07432SValerii Chubar 		goto out;
76503e07432SValerii Chubar 
76603e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
76703e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
76803e07432SValerii Chubar 	if (rc)
76903e07432SValerii Chubar 		goto out;
77003e07432SValerii Chubar 
77103e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
77203e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
77303e07432SValerii Chubar 	if (rc)
77403e07432SValerii Chubar 		goto out;
77503e07432SValerii Chubar 
77603e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
77703e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
77803e07432SValerii Chubar 
77903e07432SValerii Chubar out:
78003e07432SValerii Chubar 	if (tee_obj != TEE_HANDLE_NULL)
78103e07432SValerii Chubar 		TEE_CloseObject(tee_obj);
78203e07432SValerii Chubar 
78303e07432SValerii Chubar 	return rc;
78403e07432SValerii Chubar }
78503e07432SValerii Chubar 
78603e07432SValerii Chubar enum pkcs11_rc
78703e07432SValerii Chubar pkcs2tee_proc_params_eddsa(struct active_processing *proc,
78803e07432SValerii Chubar 			   struct pkcs11_attribute_head *proc_params)
78903e07432SValerii Chubar {
79003e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
79103e07432SValerii Chubar 	uint32_t ctx_len = 0;
79203e07432SValerii Chubar 	uint32_t flag = 0;
79303e07432SValerii Chubar 	void *ctx_data = NULL;
79403e07432SValerii Chubar 	struct serialargs args = { };
79503e07432SValerii Chubar 	struct eddsa_processing_ctx *ctx = NULL;
79603e07432SValerii Chubar 
79703e07432SValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
79803e07432SValerii Chubar 
79903e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &flag);
80003e07432SValerii Chubar 	if (rc)
80103e07432SValerii Chubar 		return rc;
80203e07432SValerii Chubar 
80303e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &ctx_len);
80403e07432SValerii Chubar 	if (rc)
80503e07432SValerii Chubar 		return rc;
80603e07432SValerii Chubar 
80703e07432SValerii Chubar 	rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
80803e07432SValerii Chubar 	if (rc)
80903e07432SValerii Chubar 		return rc;
81003e07432SValerii Chubar 
81103e07432SValerii Chubar 	if (serialargs_remaining_bytes(&args))
81203e07432SValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
81303e07432SValerii Chubar 
81403e07432SValerii Chubar 	proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
81503e07432SValerii Chubar 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
81603e07432SValerii Chubar 	if (!proc->extra_ctx)
81703e07432SValerii Chubar 		return PKCS11_CKR_DEVICE_MEMORY;
81803e07432SValerii Chubar 
81903e07432SValerii Chubar 	ctx = proc->extra_ctx;
82003e07432SValerii Chubar 	ctx->ctx_len = ctx_len;
82103e07432SValerii Chubar 	ctx->flag = flag;
82203e07432SValerii Chubar 	TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
82303e07432SValerii Chubar 
82403e07432SValerii Chubar 	return PKCS11_CKR_OK;
82503e07432SValerii Chubar }
82603e07432SValerii Chubar 
827fb279d8bSVesa Jääskeläinen size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
828fb279d8bSVesa Jääskeläinen {
829fb279d8bSVesa Jääskeläinen 	TEE_OperationInfo info = { };
830fb279d8bSVesa Jääskeläinen 
831fb279d8bSVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
832fb279d8bSVesa Jääskeläinen 
833fb279d8bSVesa Jääskeläinen 	switch (info.algorithm) {
834fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P192:
835fb279d8bSVesa Jääskeläinen 		return 24;
836fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P224:
837fb279d8bSVesa Jääskeläinen 		return 28;
838fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P256:
839fb279d8bSVesa Jääskeläinen 		return 32;
840fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P384:
841fb279d8bSVesa Jääskeläinen 		return 48;
842fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P521:
843fb279d8bSVesa Jääskeläinen 		return 66;
844fb279d8bSVesa Jääskeläinen 	default:
845fb279d8bSVesa Jääskeläinen 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
846fb279d8bSVesa Jääskeläinen 		return 0;
847fb279d8bSVesa Jääskeläinen 	}
848fb279d8bSVesa Jääskeläinen }
849cc062b46SJorge Ramirez-Ortiz 
850cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
851cc062b46SJorge Ramirez-Ortiz 				   void **pub_data, size_t *pub_size)
852cc062b46SJorge Ramirez-Ortiz {
853cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
854cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
855cc062b46SJorge Ramirez-Ortiz 	uint32_t word = 0;
856cc062b46SJorge Ramirez-Ortiz 	uint8_t byte = 0;
857cc062b46SJorge Ramirez-Ortiz 
858cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
859cc062b46SJorge Ramirez-Ortiz 
860cc062b46SJorge Ramirez-Ortiz 	/* Skip KDF */
861cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
862cc062b46SJorge Ramirez-Ortiz 	if (rc)
863cc062b46SJorge Ramirez-Ortiz 		return rc;
864cc062b46SJorge Ramirez-Ortiz 
865cc062b46SJorge Ramirez-Ortiz 	/* Shared data size, shall be 0 */
866cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
867cc062b46SJorge Ramirez-Ortiz 	if (rc || word)
868cc062b46SJorge Ramirez-Ortiz 		return rc;
869cc062b46SJorge Ramirez-Ortiz 
870cc062b46SJorge Ramirez-Ortiz 	/* Public data size and content */
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 	*pub_size = word;
876cc062b46SJorge Ramirez-Ortiz 
877cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
878cc062b46SJorge Ramirez-Ortiz 	if (rc)
879cc062b46SJorge Ramirez-Ortiz 		return rc;
880cc062b46SJorge Ramirez-Ortiz 
881cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
882cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
883cc062b46SJorge Ramirez-Ortiz 
884cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x04) {
885cc062b46SJorge Ramirez-Ortiz 		EMSG("DER compressed public key format not yet supported");
886cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
887cc062b46SJorge Ramirez-Ortiz 	}
888cc062b46SJorge Ramirez-Ortiz 
889cc062b46SJorge Ramirez-Ortiz 	*pub_size -= sizeof(uint8_t);
890cc062b46SJorge Ramirez-Ortiz 
891cc062b46SJorge Ramirez-Ortiz 	if (*pub_size >= 0x80) {
892cc062b46SJorge Ramirez-Ortiz 		EMSG("DER long definitive form not yet supported");
893cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
894cc062b46SJorge Ramirez-Ortiz 	}
895cc062b46SJorge Ramirez-Ortiz 
896cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
897cc062b46SJorge Ramirez-Ortiz 	if (rc)
898cc062b46SJorge Ramirez-Ortiz 		return rc;
899cc062b46SJorge Ramirez-Ortiz 
900cc062b46SJorge Ramirez-Ortiz 	if (serialargs_remaining_bytes(&args))
901cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
902cc062b46SJorge Ramirez-Ortiz 
903cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
904cc062b46SJorge Ramirez-Ortiz }
905cc062b46SJorge Ramirez-Ortiz 
906cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
907cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_attribute_head *proc_params,
908cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_object *obj)
909cc062b46SJorge Ramirez-Ortiz {
910cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
911cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
912cc062b46SJorge Ramirez-Ortiz 	uint32_t kdf = 0;
913cc062b46SJorge Ramirez-Ortiz 
914cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
915cc062b46SJorge Ramirez-Ortiz 
916cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &kdf);
917cc062b46SJorge Ramirez-Ortiz 	if (rc)
918cc062b46SJorge Ramirez-Ortiz 		return rc;
919cc062b46SJorge Ramirez-Ortiz 
920cc062b46SJorge Ramirez-Ortiz 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
921cc062b46SJorge Ramirez-Ortiz 	if (kdf != PKCS11_CKD_NULL) {
922cc062b46SJorge Ramirez-Ortiz 		DMSG("Only support CKD_NULL key derivation for ECDH");
923cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
924cc062b46SJorge Ramirez-Ortiz 	}
925cc062b46SJorge Ramirez-Ortiz 
926cc062b46SJorge Ramirez-Ortiz 	switch (get_object_key_bit_size(obj)) {
927cc062b46SJorge Ramirez-Ortiz 	case 192:
928cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P192;
929cc062b46SJorge Ramirez-Ortiz 		break;
930cc062b46SJorge Ramirez-Ortiz 	case 224:
931cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P224;
932cc062b46SJorge Ramirez-Ortiz 		break;
933cc062b46SJorge Ramirez-Ortiz 	case 256:
934cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P256;
935cc062b46SJorge Ramirez-Ortiz 		break;
936cc062b46SJorge Ramirez-Ortiz 	case 384:
937cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P384;
938cc062b46SJorge Ramirez-Ortiz 		break;
939cc062b46SJorge Ramirez-Ortiz 	case 521:
940cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P521;
941cc062b46SJorge Ramirez-Ortiz 		break;
942cc062b46SJorge Ramirez-Ortiz 	default:
943cc062b46SJorge Ramirez-Ortiz 		TEE_Panic(0);
944cc062b46SJorge Ramirez-Ortiz 		break;
945cc062b46SJorge Ramirez-Ortiz 	}
946cc062b46SJorge Ramirez-Ortiz 
947cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
948cc062b46SJorge Ramirez-Ortiz }
949