xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision c9cf332036ae9aac78794357b92215fc11f34473)
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 
get_curve(void * attr,size_t size)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 
ec_params2tee_keysize(void * ec_params,size_t size)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  */
ec_params2tee_curve(void * ec_params,size_t size)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 
load_tee_ec_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)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 
391*c9cf3320SVesa Jääskeläinen 		/*
392*c9cf3320SVesa Jääskeläinen 		 * Standard does not have CKA_EC_POINT for EC private keys
393*c9cf3320SVesa Jääskeläinen 		 * but that is required by TEE internal API. First try to get
394*c9cf3320SVesa Jääskeläinen 		 * hidden EC POINT and for backwards compatibility then try to
395*c9cf3320SVesa Jääskeläinen 		 * get CKA_EC_POINT value.
396*c9cf3320SVesa Jääskeläinen 		 */
397*c9cf3320SVesa Jääskeläinen 
398fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
399fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
400*c9cf3320SVesa Jääskeläinen 				       obj, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT))
401*c9cf3320SVesa Jääskeläinen 			count++;
402*c9cf3320SVesa Jääskeläinen 		else if (pkcs2tee_load_attr(&attrs[count],
403*c9cf3320SVesa Jääskeläinen 					    TEE_ATTR_ECC_PUBLIC_VALUE_X,
404fb279d8bSVesa Jääskeläinen 					    obj, PKCS11_CKA_EC_POINT))
405fb279d8bSVesa Jääskeläinen 			count++;
406fb279d8bSVesa Jääskeläinen 
407fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
408fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
409*c9cf3320SVesa Jääskeläinen 				       obj, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT))
410*c9cf3320SVesa Jääskeläinen 			count++;
411*c9cf3320SVesa Jääskeläinen 		else if (pkcs2tee_load_attr(&attrs[count],
412*c9cf3320SVesa Jääskeläinen 					    TEE_ATTR_ECC_PUBLIC_VALUE_Y,
413fb279d8bSVesa Jääskeläinen 					    obj, PKCS11_CKA_EC_POINT))
414fb279d8bSVesa Jääskeläinen 			count++;
415fb279d8bSVesa Jääskeläinen 
416fb279d8bSVesa Jääskeläinen 		if (count == 4)
417fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
418fb279d8bSVesa Jääskeläinen 
419fb279d8bSVesa Jääskeläinen 		break;
420fb279d8bSVesa Jääskeläinen 
421fb279d8bSVesa Jääskeläinen 	default:
422fb279d8bSVesa Jääskeläinen 		assert(0);
423fb279d8bSVesa Jääskeläinen 		break;
424fb279d8bSVesa Jääskeläinen 	}
425fb279d8bSVesa Jääskeläinen 
426fb279d8bSVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
427fb279d8bSVesa Jääskeläinen 		*tee_attrs = attrs;
428fb279d8bSVesa Jääskeläinen 		*tee_count = count;
429fb279d8bSVesa Jääskeläinen 	} else {
430fb279d8bSVesa Jääskeläinen 		TEE_Free(attrs);
431fb279d8bSVesa Jääskeläinen 	}
432fb279d8bSVesa Jääskeläinen 
433fb279d8bSVesa Jääskeläinen 	return rc;
434fb279d8bSVesa Jääskeläinen }
435fb279d8bSVesa Jääskeläinen 
pkcs2tee_algo_ecdsa(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)436fb279d8bSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
437fb279d8bSVesa Jääskeläinen 				   struct pkcs11_attribute_head *proc_params,
438fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj)
439fb279d8bSVesa Jääskeläinen {
440fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
441fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
442fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
443fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
444fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
445fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
446fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
447fb279d8bSVesa Jääskeläinen 		break;
448fb279d8bSVesa Jääskeläinen 	default:
449fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
450fb279d8bSVesa Jääskeläinen 	}
451fb279d8bSVesa Jääskeläinen 
452fb279d8bSVesa Jääskeläinen 	/*
453fb279d8bSVesa Jääskeläinen 	 * TODO: Fixing this in a way to support also other EC curves would
454fb279d8bSVesa Jääskeläinen 	 * require OP-TEE to be updated for newer version of GlobalPlatform API
455fb279d8bSVesa Jääskeläinen 	 */
456fb279d8bSVesa Jääskeläinen 	switch (get_object_key_bit_size(obj)) {
457fb279d8bSVesa Jääskeläinen 	case 192:
458fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P192;
459fb279d8bSVesa Jääskeläinen 		break;
460fb279d8bSVesa Jääskeläinen 	case 224:
461fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P224;
462fb279d8bSVesa Jääskeläinen 		break;
463fb279d8bSVesa Jääskeläinen 	case 256:
464fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P256;
465fb279d8bSVesa Jääskeläinen 		break;
466fb279d8bSVesa Jääskeläinen 	case 384:
467fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P384;
468fb279d8bSVesa Jääskeläinen 		break;
469fb279d8bSVesa Jääskeläinen 	case 521:
470fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P521;
471fb279d8bSVesa Jääskeläinen 		break;
472fb279d8bSVesa Jääskeläinen 	default:
473fb279d8bSVesa Jääskeläinen 		TEE_Panic(0);
474fb279d8bSVesa Jääskeläinen 		break;
475fb279d8bSVesa Jääskeläinen 	}
476fb279d8bSVesa Jääskeläinen 
477fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
478fb279d8bSVesa Jääskeläinen }
479fb279d8bSVesa Jääskeläinen 
tee2pkcs_ec_attributes(struct obj_attrs ** pub_head,struct obj_attrs ** priv_head,TEE_ObjectHandle tee_obj,size_t tee_size)48002b16804SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
48102b16804SVesa Jääskeläinen 					     struct obj_attrs **priv_head,
48202b16804SVesa Jääskeläinen 					     TEE_ObjectHandle tee_obj,
48302b16804SVesa Jääskeläinen 					     size_t tee_size)
48402b16804SVesa Jääskeläinen {
48502b16804SVesa Jääskeläinen 	void *x_ptr = NULL;
48602b16804SVesa Jääskeläinen 	void *y_ptr = NULL;
48702b16804SVesa Jääskeläinen 	uint8_t *ecpoint = NULL;
48802b16804SVesa Jääskeläinen 	size_t x_size = 0;
48902b16804SVesa Jääskeläinen 	size_t y_size = 0;
49002b16804SVesa Jääskeläinen 	size_t psize = 0;
49102b16804SVesa Jääskeläinen 	size_t qsize = 0;
49202b16804SVesa Jääskeläinen 	size_t dersize = 0;
49302b16804SVesa Jääskeläinen 	size_t poffset = 0;
49402b16804SVesa Jääskeläinen 	size_t hsize = 0;
49502b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
49602b16804SVesa Jääskeläinen 
49702b16804SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
49802b16804SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
49902b16804SVesa Jääskeläinen 	if (rc)
50002b16804SVesa Jääskeläinen 		goto out;
50102b16804SVesa Jääskeläinen 
50202b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
50302b16804SVesa Jääskeläinen 					  &x_ptr, &x_size);
50402b16804SVesa Jääskeläinen 	if (rc)
50502b16804SVesa Jääskeläinen 		goto out;
50602b16804SVesa Jääskeläinen 
50702b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
50802b16804SVesa Jääskeläinen 					  &y_ptr, &y_size);
50902b16804SVesa Jääskeläinen 	if (rc)
51002b16804SVesa Jääskeläinen 		goto x_cleanup;
51102b16804SVesa Jääskeläinen 
51202b16804SVesa Jääskeläinen 	psize = (tee_size + 7) / 8;
51302b16804SVesa Jääskeläinen 	if (x_size > psize || y_size > psize) {
51402b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_ARGUMENTS_BAD;
51502b16804SVesa Jääskeläinen 		goto y_cleanup;
51602b16804SVesa Jääskeläinen 	}
51702b16804SVesa Jääskeläinen 
51802b16804SVesa Jääskeläinen 	qsize = 1 + 2 * psize;
51902b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
52002b16804SVesa Jääskeläinen 		/* DER short definitive form up to 127 bytes */
52102b16804SVesa Jääskeläinen 		dersize = qsize + 2;
52202b16804SVesa Jääskeläinen 		hsize = 2 /* der */ + 1 /* point compression */;
52302b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
52402b16804SVesa Jääskeläinen 		/* DER long definitive form up to 255 bytes */
52502b16804SVesa Jääskeläinen 		dersize = qsize + 3;
52602b16804SVesa Jääskeläinen 		hsize = 3 /* der */ + 1 /* point compression */;
52702b16804SVesa Jääskeläinen 	} else {
52802b16804SVesa Jääskeläinen 		EMSG("Too long DER value");
52902b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
53002b16804SVesa Jääskeläinen 		goto y_cleanup;
53102b16804SVesa Jääskeläinen 	}
53202b16804SVesa Jääskeläinen 
53302b16804SVesa Jääskeläinen 	ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
53402b16804SVesa Jääskeläinen 	if (!ecpoint) {
53502b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_DEVICE_MEMORY;
53602b16804SVesa Jääskeläinen 		goto y_cleanup;
53702b16804SVesa Jääskeläinen 	}
53802b16804SVesa Jääskeläinen 
53902b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
54002b16804SVesa Jääskeläinen 		/* DER encoding */
54102b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
54202b16804SVesa Jääskeläinen 		ecpoint[1] = qsize & 0x7f;
54302b16804SVesa Jääskeläinen 
54402b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
54502b16804SVesa Jääskeläinen 		ecpoint[2] = 0x04;
54602b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
54702b16804SVesa Jääskeläinen 		/* DER encoding */
54802b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
54902b16804SVesa Jääskeläinen 		ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
55002b16804SVesa Jääskeläinen 		ecpoint[2] = qsize & 0xFF;
55102b16804SVesa Jääskeläinen 
55202b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
55302b16804SVesa Jääskeläinen 		ecpoint[3] = 0x04;
55402b16804SVesa Jääskeläinen 	}
55502b16804SVesa Jääskeläinen 
55602b16804SVesa Jääskeläinen 	poffset = 0;
55702b16804SVesa Jääskeläinen 	if (x_size < psize)
55802b16804SVesa Jääskeläinen 		poffset = psize - x_size;
55902b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
56002b16804SVesa Jääskeläinen 
56102b16804SVesa Jääskeläinen 	poffset = 0;
56202b16804SVesa Jääskeläinen 	if (y_size < psize)
56302b16804SVesa Jääskeläinen 		poffset = psize - y_size;
56402b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
56502b16804SVesa Jääskeläinen 
56602b16804SVesa Jääskeläinen 	/*
567*c9cf3320SVesa Jääskeläinen 	 * Add PKCS11_CKA_OPTEE_HIDDEN_EC_POINT to private key object and
568*c9cf3320SVesa Jääskeläinen 	 * standard PKCS11_CKA_EC_POINT to public key objects as
56902b16804SVesa Jääskeläinen 	 * TEE_PopulateTransientObject requires public x/y values
57002b16804SVesa Jääskeläinen 	 * for TEE_TYPE_ECDSA_KEYPAIR.
57102b16804SVesa Jääskeläinen 	 */
572*c9cf3320SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_OPTEE_HIDDEN_EC_POINT,
573*c9cf3320SVesa Jääskeläinen 			   ecpoint, dersize);
57402b16804SVesa Jääskeläinen 	if (rc)
57502b16804SVesa Jääskeläinen 		goto ecpoint_cleanup;
57602b16804SVesa Jääskeläinen 
57702b16804SVesa Jääskeläinen 	rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
57802b16804SVesa Jääskeläinen 
57902b16804SVesa Jääskeläinen ecpoint_cleanup:
58002b16804SVesa Jääskeläinen 	TEE_Free(ecpoint);
58102b16804SVesa Jääskeläinen y_cleanup:
58202b16804SVesa Jääskeläinen 	TEE_Free(y_ptr);
58302b16804SVesa Jääskeläinen x_cleanup:
58402b16804SVesa Jääskeläinen 	TEE_Free(x_ptr);
58502b16804SVesa Jääskeläinen out:
58602b16804SVesa Jääskeläinen 	return rc;
58702b16804SVesa Jääskeläinen }
58802b16804SVesa Jääskeläinen 
generate_ec_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)58902b16804SVesa Jääskeläinen enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
59002b16804SVesa Jääskeläinen 				struct obj_attrs **pub_head,
59102b16804SVesa Jääskeläinen 				struct obj_attrs **priv_head)
59202b16804SVesa Jääskeläinen {
59302b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
59402b16804SVesa Jääskeläinen 	void *a_ptr = NULL;
59502b16804SVesa Jääskeläinen 	uint32_t a_size = 0;
59602b16804SVesa Jääskeläinen 	uint32_t tee_size = 0;
59702b16804SVesa Jääskeläinen 	uint32_t tee_curve = 0;
59802b16804SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
59902b16804SVesa Jääskeläinen 	TEE_Attribute tee_key_attr[1] = { };
60002b16804SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
60102b16804SVesa Jääskeläinen 
60202b16804SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
60302b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
60402b16804SVesa Jääskeläinen 
60502b16804SVesa Jääskeläinen 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
60602b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
60702b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
60802b16804SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
60902b16804SVesa Jääskeläinen 		trace_attributes("public-key", *pub_head);
61002b16804SVesa Jääskeläinen 		trace_attributes("private-key", *priv_head);
61102b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
61202b16804SVesa Jääskeläinen 	}
61302b16804SVesa Jääskeläinen 
61402b16804SVesa Jääskeläinen 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
61502b16804SVesa Jääskeläinen 			      &a_ptr, &a_size) || !a_ptr) {
61602b16804SVesa Jääskeläinen 		EMSG("No EC_PARAMS attribute found in public key");
61702b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
61802b16804SVesa Jääskeläinen 	}
61902b16804SVesa Jääskeläinen 
62002b16804SVesa Jääskeläinen 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
62102b16804SVesa Jääskeläinen 	if (!tee_size)
62202b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
62302b16804SVesa Jääskeläinen 
62402b16804SVesa Jääskeläinen 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
62502b16804SVesa Jääskeläinen 
62602b16804SVesa Jääskeläinen 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
62702b16804SVesa Jääskeläinen 
62802b16804SVesa Jääskeläinen 	/* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
62902b16804SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
63002b16804SVesa Jääskeläinen 					  &tee_obj);
63102b16804SVesa Jääskeläinen 	if (res) {
63202b16804SVesa Jääskeläinen 		EMSG("Transient alloc failed with %#"PRIx32, res);
63302b16804SVesa Jääskeläinen 		return tee2pkcs_error(res);
63402b16804SVesa Jääskeläinen 	}
63502b16804SVesa Jääskeläinen 
63602b16804SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
63702b16804SVesa Jääskeläinen 	if (res) {
63802b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
63902b16804SVesa Jääskeläinen 		goto out;
64002b16804SVesa Jääskeläinen 	}
64102b16804SVesa Jääskeläinen 
64202b16804SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
64302b16804SVesa Jääskeläinen 	if (res) {
64402b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
64502b16804SVesa Jääskeläinen 		goto out;
64602b16804SVesa Jääskeläinen 	}
64702b16804SVesa Jääskeläinen 
64802b16804SVesa Jääskeläinen 	/* Private key needs the same EC_PARAMS as used by the public key */
64902b16804SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
65002b16804SVesa Jääskeläinen 	if (rc)
65102b16804SVesa Jääskeläinen 		goto out;
65202b16804SVesa Jääskeläinen 
65302b16804SVesa Jääskeläinen 	rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
65402b16804SVesa Jääskeläinen 
65502b16804SVesa Jääskeläinen out:
65602b16804SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
65702b16804SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
65802b16804SVesa Jääskeläinen 
65902b16804SVesa Jääskeläinen 	return rc;
66002b16804SVesa Jääskeläinen }
661fb279d8bSVesa Jääskeläinen 
load_tee_eddsa_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)66203e07432SValerii Chubar enum pkcs11_rc load_tee_eddsa_key_attrs(TEE_Attribute **tee_attrs,
66303e07432SValerii Chubar 					size_t *tee_count,
66403e07432SValerii Chubar 					struct pkcs11_object *obj)
66503e07432SValerii Chubar {
66603e07432SValerii Chubar 	TEE_Attribute *attrs = NULL;
66703e07432SValerii Chubar 	size_t count = 0;
66803e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
66903e07432SValerii Chubar 
67003e07432SValerii Chubar 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC_EDWARDS);
67103e07432SValerii Chubar 
67203e07432SValerii Chubar 	switch (get_class(obj->attributes)) {
67303e07432SValerii Chubar 	case PKCS11_CKO_PUBLIC_KEY:
67403e07432SValerii Chubar 		attrs = TEE_Malloc(sizeof(TEE_Attribute),
67503e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
67603e07432SValerii Chubar 		if (!attrs)
67703e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
67803e07432SValerii Chubar 
67903e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
68003e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
68103e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
68203e07432SValerii Chubar 			count++;
68303e07432SValerii Chubar 
68403e07432SValerii Chubar 		if (count == 1)
68503e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
68603e07432SValerii Chubar 
68703e07432SValerii Chubar 		break;
68803e07432SValerii Chubar 
68903e07432SValerii Chubar 	case PKCS11_CKO_PRIVATE_KEY:
69003e07432SValerii Chubar 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
69103e07432SValerii Chubar 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
69203e07432SValerii Chubar 		if (!attrs)
69303e07432SValerii Chubar 			return PKCS11_CKR_DEVICE_MEMORY;
69403e07432SValerii Chubar 
69503e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
69603e07432SValerii Chubar 				       TEE_ATTR_ED25519_PRIVATE_VALUE,
69703e07432SValerii Chubar 				       obj, PKCS11_CKA_VALUE))
69803e07432SValerii Chubar 			count++;
69903e07432SValerii Chubar 
70003e07432SValerii Chubar 		if (pkcs2tee_load_attr(&attrs[count],
70103e07432SValerii Chubar 				       TEE_ATTR_ED25519_PUBLIC_VALUE,
70203e07432SValerii Chubar 				       obj, PKCS11_CKA_EC_POINT))
70303e07432SValerii Chubar 			count++;
70403e07432SValerii Chubar 
70503e07432SValerii Chubar 		if (count == 2)
70603e07432SValerii Chubar 			rc = PKCS11_CKR_OK;
70703e07432SValerii Chubar 
70803e07432SValerii Chubar 		break;
70903e07432SValerii Chubar 
71003e07432SValerii Chubar 	default:
71103e07432SValerii Chubar 		assert(0);
71203e07432SValerii Chubar 		break;
71303e07432SValerii Chubar 	}
71403e07432SValerii Chubar 
71503e07432SValerii Chubar 	if (rc == PKCS11_CKR_OK) {
71603e07432SValerii Chubar 		*tee_attrs = attrs;
71703e07432SValerii Chubar 		*tee_count = count;
71803e07432SValerii Chubar 	} else {
71903e07432SValerii Chubar 		TEE_Free(attrs);
72003e07432SValerii Chubar 	}
72103e07432SValerii Chubar 
72203e07432SValerii Chubar 	return rc;
72303e07432SValerii Chubar }
72403e07432SValerii Chubar 
generate_eddsa_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)72503e07432SValerii Chubar enum pkcs11_rc generate_eddsa_keys(struct pkcs11_attribute_head *proc_params,
72603e07432SValerii Chubar 				   struct obj_attrs **pub_head,
72703e07432SValerii Chubar 				   struct obj_attrs **priv_head)
72803e07432SValerii Chubar {
72903e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
73003e07432SValerii Chubar 	void *a_ptr = NULL;
73103e07432SValerii Chubar 	uint32_t a_size = 0;
73203e07432SValerii Chubar 	uint32_t tee_size = 0;
73303e07432SValerii Chubar 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
73403e07432SValerii Chubar 	TEE_Result res = TEE_ERROR_GENERIC;
73503e07432SValerii Chubar 
73603e07432SValerii Chubar 	if (!proc_params || !*pub_head || !*priv_head)
73703e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
73803e07432SValerii Chubar 
73903e07432SValerii Chubar 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
74003e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
741ecd7f426SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_POINT) ||
74203e07432SValerii Chubar 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
74303e07432SValerii Chubar 		EMSG("Unexpected attribute(s) found");
74403e07432SValerii Chubar 		trace_attributes("public-key", *pub_head);
74503e07432SValerii Chubar 		trace_attributes("private-key", *priv_head);
74603e07432SValerii Chubar 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
74703e07432SValerii Chubar 	}
74803e07432SValerii Chubar 
74903e07432SValerii Chubar 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
75003e07432SValerii Chubar 			      &a_ptr, &a_size) || !a_ptr) {
75103e07432SValerii Chubar 		EMSG("No EC_PARAMS attribute found in public key");
75203e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
75303e07432SValerii Chubar 	}
75403e07432SValerii Chubar 
75503e07432SValerii Chubar 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
75603e07432SValerii Chubar 	if (!tee_size)
75703e07432SValerii Chubar 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
75803e07432SValerii Chubar 
75903e07432SValerii Chubar 	res = TEE_AllocateTransientObject(TEE_TYPE_ED25519_KEYPAIR, tee_size,
76003e07432SValerii Chubar 					  &tee_obj);
76103e07432SValerii Chubar 	if (res) {
76203e07432SValerii Chubar 		EMSG("Transient alloc failed with %#"PRIx32, res);
76303e07432SValerii Chubar 		return tee2pkcs_error(res);
76403e07432SValerii Chubar 	}
76503e07432SValerii Chubar 
76603e07432SValerii Chubar 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
76703e07432SValerii Chubar 	if (res) {
76803e07432SValerii Chubar 		rc = tee2pkcs_error(res);
76903e07432SValerii Chubar 		goto out;
77003e07432SValerii Chubar 	}
77103e07432SValerii Chubar 
772ecd7f426SValerii Chubar 	res = TEE_GenerateKey(tee_obj, tee_size, NULL, 0);
77303e07432SValerii Chubar 	if (res) {
77403e07432SValerii Chubar 		rc = tee2pkcs_error(res);
77503e07432SValerii Chubar 		goto out;
77603e07432SValerii Chubar 	}
77703e07432SValerii Chubar 
77803e07432SValerii Chubar 	/* Private key needs the same EC_PARAMS as used by the public key */
77903e07432SValerii Chubar 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
78003e07432SValerii Chubar 	if (rc)
78103e07432SValerii Chubar 		goto out;
78203e07432SValerii Chubar 
78303e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
78403e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PRIVATE_VALUE);
78503e07432SValerii Chubar 	if (rc)
78603e07432SValerii Chubar 		goto out;
78703e07432SValerii Chubar 
78803e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EC_POINT,
78903e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
79003e07432SValerii Chubar 	if (rc)
79103e07432SValerii Chubar 		goto out;
79203e07432SValerii Chubar 
79303e07432SValerii Chubar 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_EC_POINT,
79403e07432SValerii Chubar 				    tee_obj, TEE_ATTR_ED25519_PUBLIC_VALUE);
79503e07432SValerii Chubar 
79603e07432SValerii Chubar out:
79703e07432SValerii Chubar 	if (tee_obj != TEE_HANDLE_NULL)
79803e07432SValerii Chubar 		TEE_CloseObject(tee_obj);
79903e07432SValerii Chubar 
80003e07432SValerii Chubar 	return rc;
80103e07432SValerii Chubar }
80203e07432SValerii Chubar 
80303e07432SValerii Chubar enum pkcs11_rc
pkcs2tee_proc_params_eddsa(struct active_processing * proc,struct pkcs11_attribute_head * proc_params)80403e07432SValerii Chubar pkcs2tee_proc_params_eddsa(struct active_processing *proc,
80503e07432SValerii Chubar 			   struct pkcs11_attribute_head *proc_params)
80603e07432SValerii Chubar {
80703e07432SValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
80803e07432SValerii Chubar 	uint32_t ctx_len = 0;
80903e07432SValerii Chubar 	uint32_t flag = 0;
81003e07432SValerii Chubar 	void *ctx_data = NULL;
81103e07432SValerii Chubar 	struct serialargs args = { };
81203e07432SValerii Chubar 	struct eddsa_processing_ctx *ctx = NULL;
81303e07432SValerii Chubar 
81403e07432SValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
81503e07432SValerii Chubar 
81603e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &flag);
81703e07432SValerii Chubar 	if (rc)
81803e07432SValerii Chubar 		return rc;
81903e07432SValerii Chubar 
82003e07432SValerii Chubar 	rc = serialargs_get_u32(&args, &ctx_len);
82103e07432SValerii Chubar 	if (rc)
82203e07432SValerii Chubar 		return rc;
82303e07432SValerii Chubar 
82403e07432SValerii Chubar 	rc = serialargs_get_ptr(&args, &ctx_data, ctx_len);
82503e07432SValerii Chubar 	if (rc)
82603e07432SValerii Chubar 		return rc;
82703e07432SValerii Chubar 
82803e07432SValerii Chubar 	if (serialargs_remaining_bytes(&args))
82903e07432SValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
83003e07432SValerii Chubar 
83103e07432SValerii Chubar 	proc->extra_ctx = TEE_Malloc(sizeof(*ctx) + ctx_len,
83203e07432SValerii Chubar 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
83303e07432SValerii Chubar 	if (!proc->extra_ctx)
83403e07432SValerii Chubar 		return PKCS11_CKR_DEVICE_MEMORY;
83503e07432SValerii Chubar 
83603e07432SValerii Chubar 	ctx = proc->extra_ctx;
83703e07432SValerii Chubar 	ctx->ctx_len = ctx_len;
83803e07432SValerii Chubar 	ctx->flag = flag;
83903e07432SValerii Chubar 	TEE_MemMove(ctx->ctx, ctx_data, ctx_len);
84003e07432SValerii Chubar 
84103e07432SValerii Chubar 	return PKCS11_CKR_OK;
84203e07432SValerii Chubar }
84303e07432SValerii Chubar 
ecdsa_get_input_max_byte_size(TEE_OperationHandle op)844fb279d8bSVesa Jääskeläinen size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
845fb279d8bSVesa Jääskeläinen {
846fb279d8bSVesa Jääskeläinen 	TEE_OperationInfo info = { };
847fb279d8bSVesa Jääskeläinen 
848fb279d8bSVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
849fb279d8bSVesa Jääskeläinen 
850fb279d8bSVesa Jääskeläinen 	switch (info.algorithm) {
851fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P192:
852fb279d8bSVesa Jääskeläinen 		return 24;
853fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P224:
854fb279d8bSVesa Jääskeläinen 		return 28;
855fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P256:
856fb279d8bSVesa Jääskeläinen 		return 32;
857fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P384:
858fb279d8bSVesa Jääskeläinen 		return 48;
859fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P521:
860fb279d8bSVesa Jääskeläinen 		return 66;
861fb279d8bSVesa Jääskeläinen 	default:
862fb279d8bSVesa Jääskeläinen 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
863fb279d8bSVesa Jääskeläinen 		return 0;
864fb279d8bSVesa Jääskeläinen 	}
865fb279d8bSVesa Jääskeläinen }
866cc062b46SJorge Ramirez-Ortiz 
pkcs2tee_param_ecdh(struct pkcs11_attribute_head * proc_params,void ** pub_data,size_t * pub_size)867cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
868cc062b46SJorge Ramirez-Ortiz 				   void **pub_data, size_t *pub_size)
869cc062b46SJorge Ramirez-Ortiz {
870cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
871cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
872cc062b46SJorge Ramirez-Ortiz 	uint32_t word = 0;
873cc062b46SJorge Ramirez-Ortiz 	uint8_t byte = 0;
874cc062b46SJorge Ramirez-Ortiz 
875cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
876cc062b46SJorge Ramirez-Ortiz 
877cc062b46SJorge Ramirez-Ortiz 	/* Skip KDF */
878cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
879cc062b46SJorge Ramirez-Ortiz 	if (rc)
880cc062b46SJorge Ramirez-Ortiz 		return rc;
881cc062b46SJorge Ramirez-Ortiz 
882cc062b46SJorge Ramirez-Ortiz 	/* Shared data size, shall be 0 */
883cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
884cc062b46SJorge Ramirez-Ortiz 	if (rc || word)
885cc062b46SJorge Ramirez-Ortiz 		return rc;
886cc062b46SJorge Ramirez-Ortiz 
887cc062b46SJorge Ramirez-Ortiz 	/* Public data size and content */
888cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
889cc062b46SJorge Ramirez-Ortiz 	if (rc || !word)
890cc062b46SJorge Ramirez-Ortiz 		return rc;
891cc062b46SJorge Ramirez-Ortiz 
892cc062b46SJorge Ramirez-Ortiz 	*pub_size = word;
893cc062b46SJorge Ramirez-Ortiz 
894cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
895cc062b46SJorge Ramirez-Ortiz 	if (rc)
896cc062b46SJorge Ramirez-Ortiz 		return rc;
897cc062b46SJorge Ramirez-Ortiz 
898cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
899cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
900cc062b46SJorge Ramirez-Ortiz 
901cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x04) {
902cc062b46SJorge Ramirez-Ortiz 		EMSG("DER compressed public key format not yet supported");
903cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
904cc062b46SJorge Ramirez-Ortiz 	}
905cc062b46SJorge Ramirez-Ortiz 
906cc062b46SJorge Ramirez-Ortiz 	*pub_size -= sizeof(uint8_t);
907cc062b46SJorge Ramirez-Ortiz 
908cc062b46SJorge Ramirez-Ortiz 	if (*pub_size >= 0x80) {
909cc062b46SJorge Ramirez-Ortiz 		EMSG("DER long definitive form not yet supported");
910cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
911cc062b46SJorge Ramirez-Ortiz 	}
912cc062b46SJorge Ramirez-Ortiz 
913cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
914cc062b46SJorge Ramirez-Ortiz 	if (rc)
915cc062b46SJorge Ramirez-Ortiz 		return rc;
916cc062b46SJorge Ramirez-Ortiz 
917cc062b46SJorge Ramirez-Ortiz 	if (serialargs_remaining_bytes(&args))
918cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
919cc062b46SJorge Ramirez-Ortiz 
920cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
921cc062b46SJorge Ramirez-Ortiz }
922cc062b46SJorge Ramirez-Ortiz 
pkcs2tee_algo_ecdh(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)923cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
924cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_attribute_head *proc_params,
925cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_object *obj)
926cc062b46SJorge Ramirez-Ortiz {
927cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
928cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
929cc062b46SJorge Ramirez-Ortiz 	uint32_t kdf = 0;
930cc062b46SJorge Ramirez-Ortiz 
931cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
932cc062b46SJorge Ramirez-Ortiz 
933cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &kdf);
934cc062b46SJorge Ramirez-Ortiz 	if (rc)
935cc062b46SJorge Ramirez-Ortiz 		return rc;
936cc062b46SJorge Ramirez-Ortiz 
937cc062b46SJorge Ramirez-Ortiz 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
938cc062b46SJorge Ramirez-Ortiz 	if (kdf != PKCS11_CKD_NULL) {
939cc062b46SJorge Ramirez-Ortiz 		DMSG("Only support CKD_NULL key derivation for ECDH");
940cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
941cc062b46SJorge Ramirez-Ortiz 	}
942cc062b46SJorge Ramirez-Ortiz 
943cc062b46SJorge Ramirez-Ortiz 	switch (get_object_key_bit_size(obj)) {
944cc062b46SJorge Ramirez-Ortiz 	case 192:
945cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P192;
946cc062b46SJorge Ramirez-Ortiz 		break;
947cc062b46SJorge Ramirez-Ortiz 	case 224:
948cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P224;
949cc062b46SJorge Ramirez-Ortiz 		break;
950cc062b46SJorge Ramirez-Ortiz 	case 256:
951cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P256;
952cc062b46SJorge Ramirez-Ortiz 		break;
953cc062b46SJorge Ramirez-Ortiz 	case 384:
954cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P384;
955cc062b46SJorge Ramirez-Ortiz 		break;
956cc062b46SJorge Ramirez-Ortiz 	case 521:
957cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P521;
958cc062b46SJorge Ramirez-Ortiz 		break;
959cc062b46SJorge Ramirez-Ortiz 	default:
960cc062b46SJorge Ramirez-Ortiz 		TEE_Panic(0);
961cc062b46SJorge Ramirez-Ortiz 		break;
962cc062b46SJorge Ramirez-Ortiz 	}
963cc062b46SJorge Ramirez-Ortiz 
964cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
965cc062b46SJorge Ramirez-Ortiz }
966