xref: /optee_os/ta/pkcs11/src/processing_ec.c (revision cc062b4691e67702556da35e57d526d447ed211c)
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"
1502b16804SVesa Jääskeläinen #include "processing.h"
1602b16804SVesa Jääskeläinen 
1702b16804SVesa Jääskeläinen /*
1802b16804SVesa Jääskeläinen  * DER encoded EC parameters generated with script:
1902b16804SVesa Jääskeläinen  *   ta/pkcs11/scripts/dump_ec_curve_params.sh
2002b16804SVesa Jääskeläinen  */
2102b16804SVesa Jääskeläinen 
2202b16804SVesa Jääskeläinen static const uint8_t prime192v1_name_der[] = {
2302b16804SVesa Jääskeläinen 	0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
2402b16804SVesa Jääskeläinen 	0x01, 0x01,
2502b16804SVesa Jääskeläinen };
2602b16804SVesa Jääskeläinen 
2702b16804SVesa Jääskeläinen static const uint8_t secp224r1_name_der[] = {
2802b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x21,
2902b16804SVesa Jääskeläinen };
3002b16804SVesa Jääskeläinen 
3102b16804SVesa Jääskeläinen static const uint8_t prime256v1_name_der[] = {
3202b16804SVesa Jääskeläinen 	0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
3302b16804SVesa Jääskeläinen 	0x01, 0x07,
3402b16804SVesa Jääskeläinen };
3502b16804SVesa Jääskeläinen 
3602b16804SVesa Jääskeläinen static const uint8_t secp384r1_name_der[] = {
3702b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
3802b16804SVesa Jääskeläinen };
3902b16804SVesa Jääskeläinen 
4002b16804SVesa Jääskeläinen static const uint8_t secp521r1_name_der[] = {
4102b16804SVesa Jääskeläinen 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
4202b16804SVesa Jääskeläinen };
4302b16804SVesa Jääskeläinen 
4402b16804SVesa Jääskeläinen static const uint8_t prime192v1_oid_der[] = {
4502b16804SVesa Jääskeläinen 	0x30, 0x81, 0xc7, 0x02, 0x01, 0x01, 0x30, 0x24,
4602b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
4702b16804SVesa Jääskeläinen 	0x01, 0x02, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff,
4802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
5002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x30, 0x4b, 0x04, 0x18,
5102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
5302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
5402b16804SVesa Jääskeläinen 	0x04, 0x18, 0x64, 0x21, 0x05, 0x19, 0xe5, 0x9c,
5502b16804SVesa Jääskeläinen 	0x80, 0xe7, 0x0f, 0xa7, 0xe9, 0xab, 0x72, 0x24,
5602b16804SVesa Jääskeläinen 	0x30, 0x49, 0xfe, 0xb8, 0xde, 0xec, 0xc1, 0x46,
5702b16804SVesa Jääskeläinen 	0xb9, 0xb1, 0x03, 0x15, 0x00, 0x30, 0x45, 0xae,
5802b16804SVesa Jääskeläinen 	0x6f, 0xc8, 0x42, 0x2f, 0x64, 0xed, 0x57, 0x95,
5902b16804SVesa Jääskeläinen 	0x28, 0xd3, 0x81, 0x20, 0xea, 0xe1, 0x21, 0x96,
6002b16804SVesa Jääskeläinen 	0xd5, 0x04, 0x31, 0x04, 0x18, 0x8d, 0xa8, 0x0e,
6102b16804SVesa Jääskeläinen 	0xb0, 0x30, 0x90, 0xf6, 0x7c, 0xbf, 0x20, 0xeb,
6202b16804SVesa Jääskeläinen 	0x43, 0xa1, 0x88, 0x00, 0xf4, 0xff, 0x0a, 0xfd,
6302b16804SVesa Jääskeläinen 	0x82, 0xff, 0x10, 0x12, 0x07, 0x19, 0x2b, 0x95,
6402b16804SVesa Jääskeläinen 	0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
6502b16804SVesa Jääskeläinen 	0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1,
6602b16804SVesa Jääskeläinen 	0x1e, 0x79, 0x48, 0x11, 0x02, 0x19, 0x00, 0xff,
6702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
6802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0x99, 0xde, 0xf8, 0x36, 0x14,
6902b16804SVesa Jääskeläinen 	0x6b, 0xc9, 0xb1, 0xb4, 0xd2, 0x28, 0x31, 0x02,
7002b16804SVesa Jääskeläinen 	0x01, 0x01,
7102b16804SVesa Jääskeläinen };
7202b16804SVesa Jääskeläinen 
7302b16804SVesa Jääskeläinen static const uint8_t secp224r1_oid_der[] = {
7402b16804SVesa Jääskeläinen 	0x30, 0x81, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x28,
7502b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
7602b16804SVesa Jääskeläinen 	0x01, 0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff,
7702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
7802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
7902b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
8002b16804SVesa Jääskeläinen 	0x30, 0x53, 0x04, 0x1c, 0xff, 0xff, 0xff, 0xff,
8102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
8302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
8402b16804SVesa Jääskeläinen 	0x04, 0x1c, 0xb4, 0x05, 0x0a, 0x85, 0x0c, 0x04,
8502b16804SVesa Jääskeläinen 	0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44,
8602b16804SVesa Jääskeläinen 	0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0x0b,
8702b16804SVesa Jääskeläinen 	0x39, 0x43, 0x23, 0x55, 0xff, 0xb4, 0x03, 0x15,
8802b16804SVesa Jääskeläinen 	0x00, 0xbd, 0x71, 0x34, 0x47, 0x99, 0xd5, 0xc7,
8902b16804SVesa Jääskeläinen 	0xfc, 0xdc, 0x45, 0xb5, 0x9f, 0xa3, 0xb9, 0xab,
9002b16804SVesa Jääskeläinen 	0x8f, 0x6a, 0x94, 0x8b, 0xc5, 0x04, 0x39, 0x04,
9102b16804SVesa Jääskeläinen 	0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
9202b16804SVesa Jääskeläinen 	0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
9302b16804SVesa Jääskeläinen 	0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
9402b16804SVesa Jääskeläinen 	0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88,
9502b16804SVesa Jääskeläinen 	0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
9602b16804SVesa Jääskeläinen 	0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
9702b16804SVesa Jääskeläinen 	0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
9802b16804SVesa Jääskeläinen 	0x02, 0x1d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
9902b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
10002b16804SVesa Jääskeläinen 	0xff, 0x16, 0xa2, 0xe0, 0xb8, 0xf0, 0x3e, 0x13,
10102b16804SVesa Jääskeläinen 	0xdd, 0x29, 0x45, 0x5c, 0x5c, 0x2a, 0x3d, 0x02,
10202b16804SVesa Jääskeläinen 	0x01, 0x01,
10302b16804SVesa Jääskeläinen };
10402b16804SVesa Jääskeläinen 
10502b16804SVesa Jääskeläinen static const uint8_t prime256v1_oid_der[] = {
10602b16804SVesa Jääskeläinen 	0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c,
10702b16804SVesa Jääskeläinen 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
10802b16804SVesa Jääskeläinen 	0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
10902b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
11002b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11202b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20,
11302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
11402b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11502b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
11602b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
11702b16804SVesa Jääskeläinen 	0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
11802b16804SVesa Jääskeläinen 	0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
11902b16804SVesa Jääskeläinen 	0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
12002b16804SVesa Jääskeläinen 	0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
12102b16804SVesa Jääskeläinen 	0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36,
12202b16804SVesa Jääskeläinen 	0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
12302b16804SVesa Jääskeläinen 	0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e,
12402b16804SVesa Jääskeläinen 	0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2,
12502b16804SVesa Jääskeläinen 	0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
12602b16804SVesa Jääskeläinen 	0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
12702b16804SVesa Jääskeläinen 	0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45,
12802b16804SVesa Jääskeläinen 	0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
12902b16804SVesa Jääskeläinen 	0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
13002b16804SVesa Jääskeläinen 	0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
13102b16804SVesa Jääskeläinen 	0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
13202b16804SVesa Jääskeläinen 	0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff,
13302b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
13402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
13502b16804SVesa Jääskeläinen 	0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
13602b16804SVesa Jääskeläinen 	0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02,
13702b16804SVesa Jääskeläinen 	0x01, 0x01,
13802b16804SVesa Jääskeläinen };
13902b16804SVesa Jääskeläinen 
14002b16804SVesa Jääskeläinen static const uint8_t secp384r1_oid_der[] = {
14102b16804SVesa Jääskeläinen 	0x30, 0x82, 0x01, 0x57, 0x02, 0x01, 0x01, 0x30,
14202b16804SVesa Jääskeläinen 	0x3c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
14302b16804SVesa Jääskeläinen 	0x01, 0x01, 0x02, 0x31, 0x00, 0xff, 0xff, 0xff,
14402b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 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, 0xfe, 0xff, 0xff, 0xff,
14802b16804SVesa Jääskeläinen 	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14902b16804SVesa Jääskeläinen 	0x00, 0xff, 0xff, 0xff, 0xff, 0x30, 0x7b, 0x04,
15002b16804SVesa Jääskeläinen 	0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
15102b16804SVesa Jääskeläinen 	0xff, 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 	0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
15502b16804SVesa Jääskeläinen 	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
15602b16804SVesa Jääskeläinen 	0xfc, 0x04, 0x30, 0xb3, 0x31, 0x2f, 0xa7, 0xe2,
15702b16804SVesa Jääskeläinen 	0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, 0xe3,
15802b16804SVesa Jääskeläinen 	0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe,
15902b16804SVesa Jääskeläinen 	0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8f, 0x50,
16002b16804SVesa Jääskeläinen 	0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a,
16102b16804SVesa Jääskeläinen 	0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3,
16202b16804SVesa Jääskeläinen 	0xec, 0x2a, 0xef, 0x03, 0x15, 0x00, 0xa3, 0x35,
16302b16804SVesa Jääskeläinen 	0x92, 0x6a, 0xa3, 0x19, 0xa2, 0x7a, 0x1d, 0x00,
16402b16804SVesa Jääskeläinen 	0x89, 0x6a, 0x67, 0x73, 0xa4, 0x82, 0x7a, 0xcd,
16502b16804SVesa Jääskeläinen 	0xac, 0x73, 0x04, 0x61, 0x04, 0xaa, 0x87, 0xca,
16602b16804SVesa Jääskeläinen 	0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7,
16702b16804SVesa Jääskeläinen 	0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b,
16802b16804SVesa Jääskeläinen 	0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41,
16902b16804SVesa Jääskeläinen 	0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2,
17002b16804SVesa Jääskeläinen 	0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e,
17102b16804SVesa Jääskeläinen 	0x38, 0x72, 0x76, 0x0a, 0xb7, 0x36, 0x17, 0xde,
17202b16804SVesa Jääskeläinen 	0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98,
17302b16804SVesa Jääskeläinen 	0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d,
17402b16804SVesa Jääskeläinen 	0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31,
17502b16804SVesa Jääskeläinen 	0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1,
17602b16804SVesa Jääskeläinen 	0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d,
17702b16804SVesa Jääskeläinen 	0x7c, 0x90, 0xea, 0x0e, 0x5f, 0x02, 0x31, 0x00,
17802b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
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 	0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
18202b16804SVesa Jääskeläinen 	0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
18302b16804SVesa Jääskeläinen 	0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,
18402b16804SVesa Jääskeläinen 	0x02, 0x01, 0x01,
18502b16804SVesa Jääskeläinen };
18602b16804SVesa Jääskeläinen 
18702b16804SVesa Jääskeläinen static const uint8_t secp521r1_oid_der[] = {
18802b16804SVesa Jääskeläinen 	0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30,
18902b16804SVesa Jääskeläinen 	0x4d, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
19002b16804SVesa Jääskeläinen 	0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
19102b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81,
19902b16804SVesa Jääskeläinen 	0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
20002b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 0xff, 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, 0xfc, 0x04, 0x42, 0x00,
20802b16804SVesa Jääskeläinen 	0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
20902b16804SVesa Jääskeläinen 	0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40,
21002b16804SVesa Jääskeläinen 	0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15,
21102b16804SVesa Jääskeläinen 	0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
21202b16804SVesa Jääskeläinen 	0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93,
21302b16804SVesa Jääskeläinen 	0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf,
21402b16804SVesa Jääskeläinen 	0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
21502b16804SVesa Jääskeläinen 	0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f,
21602b16804SVesa Jääskeläinen 	0x00, 0x03, 0x15, 0x00, 0xd0, 0x9e, 0x88, 0x00,
21702b16804SVesa Jääskeläinen 	0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
21802b16804SVesa Jääskeläinen 	0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba,
21902b16804SVesa Jääskeläinen 	0x04, 0x81, 0x85, 0x04, 0x00, 0xc6, 0x85, 0x8e,
22002b16804SVesa Jääskeläinen 	0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
22102b16804SVesa Jääskeläinen 	0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64,
22202b16804SVesa Jääskeläinen 	0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28,
22302b16804SVesa Jääskeläinen 	0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
22402b16804SVesa Jääskeläinen 	0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d,
22502b16804SVesa Jääskeläinen 	0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48,
22602b16804SVesa Jääskeläinen 	0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
22702b16804SVesa Jääskeläinen 	0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18,
22802b16804SVesa Jääskeläinen 	0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04,
22902b16804SVesa Jääskeläinen 	0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
23002b16804SVesa Jääskeläinen 	0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
23102b16804SVesa Jääskeläinen 	0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c,
23202b16804SVesa Jääskeläinen 	0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
23302b16804SVesa Jääskeläinen 	0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
23402b16804SVesa Jääskeläinen 	0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40,
23502b16804SVesa Jääskeläinen 	0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
23602b16804SVesa Jääskeläinen 	0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
23702b16804SVesa Jääskeläinen 	0xff, 0xff, 0xff, 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, 0xfa, 0x51, 0x86, 0x87, 0x83,
24102b16804SVesa Jääskeläinen 	0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
24202b16804SVesa Jääskeläinen 	0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8,
24302b16804SVesa Jääskeläinen 	0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e,
24402b16804SVesa Jääskeläinen 	0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
24502b16804SVesa Jääskeläinen };
24602b16804SVesa Jääskeläinen 
24702b16804SVesa Jääskeläinen struct supported_ecc_curve {
24802b16804SVesa Jääskeläinen 	const uint8_t *oid_der;
24902b16804SVesa Jääskeläinen 	size_t oid_size;
25002b16804SVesa Jääskeläinen 	const uint8_t *name_der;
25102b16804SVesa Jääskeläinen 	size_t name_size;
25202b16804SVesa Jääskeläinen 	size_t key_size;
25302b16804SVesa Jääskeläinen 	uint32_t tee_id;
25402b16804SVesa Jääskeläinen 	const char *label;
25502b16804SVesa Jääskeläinen 	size_t label_size;
25602b16804SVesa Jääskeläinen };
25702b16804SVesa Jääskeläinen 
25802b16804SVesa Jääskeläinen #define ECC_CURVE(_tee_id, _key_size, _label)			\
25902b16804SVesa Jääskeläinen 	{							\
26002b16804SVesa Jääskeläinen 		.tee_id = (_tee_id),				\
26102b16804SVesa Jääskeläinen 		.key_size = (_key_size),			\
26202b16804SVesa Jääskeläinen 		.oid_der = _label ## _oid_der,			\
26302b16804SVesa Jääskeläinen 		.oid_size = sizeof(_label ## _oid_der),		\
26402b16804SVesa Jääskeläinen 		.name_der = _label ## _name_der,		\
26502b16804SVesa Jääskeläinen 		.name_size = sizeof(_label ## _name_der),	\
26602b16804SVesa Jääskeläinen 		.label = #_label,				\
26702b16804SVesa Jääskeläinen 		.label_size = sizeof(#_label) - 1,		\
26802b16804SVesa Jääskeläinen 	}
26902b16804SVesa Jääskeläinen 
27002b16804SVesa Jääskeläinen static const struct supported_ecc_curve ec_curve_param[] = {
27102b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P192, 192, prime192v1),
27202b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P224, 224, secp224r1),
27302b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P256, 256, prime256v1),
27402b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P384, 384, secp384r1),
27502b16804SVesa Jääskeläinen 	ECC_CURVE(TEE_ECC_CURVE_NIST_P521, 521, secp521r1),
27602b16804SVesa Jääskeläinen };
27702b16804SVesa Jääskeläinen 
27802b16804SVesa Jääskeläinen static const struct supported_ecc_curve *get_curve(void *attr, size_t size)
27902b16804SVesa Jääskeläinen {
28002b16804SVesa Jääskeläinen 	size_t idx = 0;
28102b16804SVesa Jääskeläinen 
28202b16804SVesa Jääskeläinen 	/* Weak: not a real DER parser: try by params then by named curve */
28302b16804SVesa Jääskeläinen 	for (idx = 0; idx < ARRAY_SIZE(ec_curve_param); idx++) {
28402b16804SVesa Jääskeläinen 		const struct supported_ecc_curve *curve = ec_curve_param + idx;
28502b16804SVesa Jääskeläinen 
28602b16804SVesa Jääskeläinen 		if (size == curve->oid_size &&
28702b16804SVesa Jääskeläinen 		    !TEE_MemCompare(attr, curve->oid_der, curve->oid_size))
28802b16804SVesa Jääskeläinen 			return curve;
28902b16804SVesa Jääskeläinen 
29002b16804SVesa Jääskeläinen 		if (size == curve->name_size &&
29102b16804SVesa Jääskeläinen 		    !TEE_MemCompare(attr, curve->name_der, curve->name_size))
29202b16804SVesa Jääskeläinen 			return curve;
29302b16804SVesa Jääskeläinen 	}
29402b16804SVesa Jääskeläinen 
29502b16804SVesa Jääskeläinen 	return NULL;
29602b16804SVesa Jääskeläinen }
29702b16804SVesa Jääskeläinen 
29802b16804SVesa Jääskeläinen size_t ec_params2tee_keysize(void *ec_params, size_t size)
29902b16804SVesa Jääskeläinen {
30002b16804SVesa Jääskeläinen 	const struct supported_ecc_curve *curve = get_curve(ec_params, size);
30102b16804SVesa Jääskeläinen 
30202b16804SVesa Jääskeläinen 	if (!curve)
30302b16804SVesa Jääskeläinen 		return 0;
30402b16804SVesa Jääskeläinen 
30502b16804SVesa Jääskeläinen 	return curve->key_size;
30602b16804SVesa Jääskeläinen }
30702b16804SVesa Jääskeläinen 
30802b16804SVesa Jääskeläinen /*
30902b16804SVesa Jääskeläinen  * This function intentionally panics if the curve is not found.
31002b16804SVesa Jääskeläinen  * Use ec_params2tee_keysize() to check the curve is supported by
31102b16804SVesa Jääskeläinen  * the internal core API.
31202b16804SVesa Jääskeläinen  */
31302b16804SVesa Jääskeläinen uint32_t ec_params2tee_curve(void *ec_params, size_t size)
31402b16804SVesa Jääskeläinen {
31502b16804SVesa Jääskeläinen 	const struct supported_ecc_curve *curve = get_curve(ec_params, size);
31602b16804SVesa Jääskeläinen 
31702b16804SVesa Jääskeläinen 	assert(curve);
31802b16804SVesa Jääskeläinen 
31902b16804SVesa Jääskeläinen 	return curve->tee_id;
32002b16804SVesa Jääskeläinen }
32102b16804SVesa Jääskeläinen 
322fb279d8bSVesa Jääskeläinen enum pkcs11_rc load_tee_ec_key_attrs(TEE_Attribute **tee_attrs,
323fb279d8bSVesa Jääskeläinen 				     size_t *tee_count,
324fb279d8bSVesa Jääskeläinen 				     struct pkcs11_object *obj)
325fb279d8bSVesa Jääskeläinen {
326fb279d8bSVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
327fb279d8bSVesa Jääskeläinen 	size_t count = 0;
328fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
329fb279d8bSVesa Jääskeläinen 
330fb279d8bSVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_EC);
331fb279d8bSVesa Jääskeläinen 
332fb279d8bSVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
333fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
334fb279d8bSVesa Jääskeläinen 		attrs = TEE_Malloc(3 * sizeof(TEE_Attribute),
335fb279d8bSVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
336fb279d8bSVesa Jääskeläinen 		if (!attrs)
337fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
338fb279d8bSVesa Jääskeläinen 
339fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
340fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_PARAMS))
341fb279d8bSVesa Jääskeläinen 			count++;
342fb279d8bSVesa Jääskeläinen 
343fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
344fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
345fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
346fb279d8bSVesa Jääskeläinen 			count++;
347fb279d8bSVesa Jääskeläinen 
348fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
349fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
350fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
351fb279d8bSVesa Jääskeläinen 			count++;
352fb279d8bSVesa Jääskeläinen 
353fb279d8bSVesa Jääskeläinen 		if (count == 3)
354fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
355fb279d8bSVesa Jääskeläinen 
356fb279d8bSVesa Jääskeläinen 		break;
357fb279d8bSVesa Jääskeläinen 
358fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
359fb279d8bSVesa Jääskeläinen 		attrs = TEE_Malloc(4 * sizeof(TEE_Attribute),
360fb279d8bSVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
361fb279d8bSVesa Jääskeläinen 		if (!attrs)
362fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
363fb279d8bSVesa Jääskeläinen 
364fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_ECC_CURVE,
365fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_PARAMS))
366fb279d8bSVesa Jääskeläinen 			count++;
367fb279d8bSVesa Jääskeläinen 
368fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
369fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PRIVATE_VALUE,
370fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_VALUE))
371fb279d8bSVesa Jääskeläinen 			count++;
372fb279d8bSVesa Jääskeläinen 
373fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
374fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_X,
375fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
376fb279d8bSVesa Jääskeläinen 			count++;
377fb279d8bSVesa Jääskeläinen 
378fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
379fb279d8bSVesa Jääskeläinen 				       TEE_ATTR_ECC_PUBLIC_VALUE_Y,
380fb279d8bSVesa Jääskeläinen 				       obj, PKCS11_CKA_EC_POINT))
381fb279d8bSVesa Jääskeläinen 			count++;
382fb279d8bSVesa Jääskeläinen 
383fb279d8bSVesa Jääskeläinen 		if (count == 4)
384fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
385fb279d8bSVesa Jääskeläinen 
386fb279d8bSVesa Jääskeläinen 		break;
387fb279d8bSVesa Jääskeläinen 
388fb279d8bSVesa Jääskeläinen 	default:
389fb279d8bSVesa Jääskeläinen 		assert(0);
390fb279d8bSVesa Jääskeläinen 		break;
391fb279d8bSVesa Jääskeläinen 	}
392fb279d8bSVesa Jääskeläinen 
393fb279d8bSVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
394fb279d8bSVesa Jääskeläinen 		*tee_attrs = attrs;
395fb279d8bSVesa Jääskeläinen 		*tee_count = count;
396fb279d8bSVesa Jääskeläinen 	} else {
397fb279d8bSVesa Jääskeläinen 		TEE_Free(attrs);
398fb279d8bSVesa Jääskeläinen 	}
399fb279d8bSVesa Jääskeläinen 
400fb279d8bSVesa Jääskeläinen 	return rc;
401fb279d8bSVesa Jääskeläinen }
402fb279d8bSVesa Jääskeläinen 
403fb279d8bSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_ecdsa(uint32_t *tee_id,
404fb279d8bSVesa Jääskeläinen 				   struct pkcs11_attribute_head *proc_params,
405fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj)
406fb279d8bSVesa Jääskeläinen {
407fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
408fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
409fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
410fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
411fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
412fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
413fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
414fb279d8bSVesa Jääskeläinen 		break;
415fb279d8bSVesa Jääskeläinen 	default:
416fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
417fb279d8bSVesa Jääskeläinen 	}
418fb279d8bSVesa Jääskeläinen 
419fb279d8bSVesa Jääskeläinen 	/*
420fb279d8bSVesa Jääskeläinen 	 * TODO: Fixing this in a way to support also other EC curves would
421fb279d8bSVesa Jääskeläinen 	 * require OP-TEE to be updated for newer version of GlobalPlatform API
422fb279d8bSVesa Jääskeläinen 	 */
423fb279d8bSVesa Jääskeläinen 	switch (get_object_key_bit_size(obj)) {
424fb279d8bSVesa Jääskeläinen 	case 192:
425fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P192;
426fb279d8bSVesa Jääskeläinen 		break;
427fb279d8bSVesa Jääskeläinen 	case 224:
428fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P224;
429fb279d8bSVesa Jääskeläinen 		break;
430fb279d8bSVesa Jääskeläinen 	case 256:
431fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P256;
432fb279d8bSVesa Jääskeläinen 		break;
433fb279d8bSVesa Jääskeläinen 	case 384:
434fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P384;
435fb279d8bSVesa Jääskeläinen 		break;
436fb279d8bSVesa Jääskeläinen 	case 521:
437fb279d8bSVesa Jääskeläinen 		*tee_id = TEE_ALG_ECDSA_P521;
438fb279d8bSVesa Jääskeläinen 		break;
439fb279d8bSVesa Jääskeläinen 	default:
440fb279d8bSVesa Jääskeläinen 		TEE_Panic(0);
441fb279d8bSVesa Jääskeläinen 		break;
442fb279d8bSVesa Jääskeläinen 	}
443fb279d8bSVesa Jääskeläinen 
444fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
445fb279d8bSVesa Jääskeläinen }
446fb279d8bSVesa Jääskeläinen 
44702b16804SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_ec_attributes(struct obj_attrs **pub_head,
44802b16804SVesa Jääskeläinen 					     struct obj_attrs **priv_head,
44902b16804SVesa Jääskeläinen 					     TEE_ObjectHandle tee_obj,
45002b16804SVesa Jääskeläinen 					     size_t tee_size)
45102b16804SVesa Jääskeläinen {
45202b16804SVesa Jääskeläinen 	void *x_ptr = NULL;
45302b16804SVesa Jääskeläinen 	void *y_ptr = NULL;
45402b16804SVesa Jääskeläinen 	uint8_t *ecpoint = NULL;
45502b16804SVesa Jääskeläinen 	size_t x_size = 0;
45602b16804SVesa Jääskeläinen 	size_t y_size = 0;
45702b16804SVesa Jääskeläinen 	size_t psize = 0;
45802b16804SVesa Jääskeläinen 	size_t qsize = 0;
45902b16804SVesa Jääskeläinen 	size_t dersize = 0;
46002b16804SVesa Jääskeläinen 	size_t poffset = 0;
46102b16804SVesa Jääskeläinen 	size_t hsize = 0;
46202b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
46302b16804SVesa Jääskeläinen 
46402b16804SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_VALUE,
46502b16804SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_ECC_PRIVATE_VALUE);
46602b16804SVesa Jääskeläinen 	if (rc)
46702b16804SVesa Jääskeläinen 		goto out;
46802b16804SVesa Jääskeläinen 
46902b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_X,
47002b16804SVesa Jääskeläinen 					  &x_ptr, &x_size);
47102b16804SVesa Jääskeläinen 	if (rc)
47202b16804SVesa Jääskeläinen 		goto out;
47302b16804SVesa Jääskeläinen 
47402b16804SVesa Jääskeläinen 	rc = alloc_get_tee_attribute_data(tee_obj, TEE_ATTR_ECC_PUBLIC_VALUE_Y,
47502b16804SVesa Jääskeläinen 					  &y_ptr, &y_size);
47602b16804SVesa Jääskeläinen 	if (rc)
47702b16804SVesa Jääskeläinen 		goto x_cleanup;
47802b16804SVesa Jääskeläinen 
47902b16804SVesa Jääskeläinen 	psize = (tee_size + 7) / 8;
48002b16804SVesa Jääskeläinen 	if (x_size > psize || y_size > psize) {
48102b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_ARGUMENTS_BAD;
48202b16804SVesa Jääskeläinen 		goto y_cleanup;
48302b16804SVesa Jääskeläinen 	}
48402b16804SVesa Jääskeläinen 
48502b16804SVesa Jääskeläinen 	qsize = 1 + 2 * psize;
48602b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
48702b16804SVesa Jääskeläinen 		/* DER short definitive form up to 127 bytes */
48802b16804SVesa Jääskeläinen 		dersize = qsize + 2;
48902b16804SVesa Jääskeläinen 		hsize = 2 /* der */ + 1 /* point compression */;
49002b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
49102b16804SVesa Jääskeläinen 		/* DER long definitive form up to 255 bytes */
49202b16804SVesa Jääskeläinen 		dersize = qsize + 3;
49302b16804SVesa Jääskeläinen 		hsize = 3 /* der */ + 1 /* point compression */;
49402b16804SVesa Jääskeläinen 	} else {
49502b16804SVesa Jääskeläinen 		EMSG("Too long DER value");
49602b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_MECHANISM_PARAM_INVALID;
49702b16804SVesa Jääskeläinen 		goto y_cleanup;
49802b16804SVesa Jääskeläinen 	}
49902b16804SVesa Jääskeläinen 
50002b16804SVesa Jääskeläinen 	ecpoint = TEE_Malloc(dersize, TEE_MALLOC_FILL_ZERO);
50102b16804SVesa Jääskeläinen 	if (!ecpoint) {
50202b16804SVesa Jääskeläinen 		rc = PKCS11_CKR_DEVICE_MEMORY;
50302b16804SVesa Jääskeläinen 		goto y_cleanup;
50402b16804SVesa Jääskeläinen 	}
50502b16804SVesa Jääskeläinen 
50602b16804SVesa Jääskeläinen 	if (qsize < 0x80) {
50702b16804SVesa Jääskeläinen 		/* DER encoding */
50802b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
50902b16804SVesa Jääskeläinen 		ecpoint[1] = qsize & 0x7f;
51002b16804SVesa Jääskeläinen 
51102b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
51202b16804SVesa Jääskeläinen 		ecpoint[2] = 0x04;
51302b16804SVesa Jääskeläinen 	} else if (qsize < 0x100) {
51402b16804SVesa Jääskeläinen 		/* DER encoding */
51502b16804SVesa Jääskeläinen 		ecpoint[0] = 0x04;
51602b16804SVesa Jääskeläinen 		ecpoint[1] = 0x80 | 0x01; /* long form, one size octet */
51702b16804SVesa Jääskeläinen 		ecpoint[2] = qsize & 0xFF;
51802b16804SVesa Jääskeläinen 
51902b16804SVesa Jääskeläinen 		/* Only UNCOMPRESSED ECPOINT is currently supported */
52002b16804SVesa Jääskeläinen 		ecpoint[3] = 0x04;
52102b16804SVesa Jääskeläinen 	}
52202b16804SVesa Jääskeläinen 
52302b16804SVesa Jääskeläinen 	poffset = 0;
52402b16804SVesa Jääskeläinen 	if (x_size < psize)
52502b16804SVesa Jääskeläinen 		poffset = psize - x_size;
52602b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + poffset, x_ptr, x_size);
52702b16804SVesa Jääskeläinen 
52802b16804SVesa Jääskeläinen 	poffset = 0;
52902b16804SVesa Jääskeläinen 	if (y_size < psize)
53002b16804SVesa Jääskeläinen 		poffset = psize - y_size;
53102b16804SVesa Jääskeläinen 	TEE_MemMove(ecpoint + hsize + psize + poffset, y_ptr, y_size);
53202b16804SVesa Jääskeläinen 
53302b16804SVesa Jääskeläinen 	/*
53402b16804SVesa Jääskeläinen 	 * Add EC_POINT on both private and public key objects as
53502b16804SVesa Jääskeläinen 	 * TEE_PopulateTransientObject requires public x/y values
53602b16804SVesa Jääskeläinen 	 * for TEE_TYPE_ECDSA_KEYPAIR.
53702b16804SVesa Jääskeläinen 	 */
53802b16804SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
53902b16804SVesa Jääskeläinen 	if (rc)
54002b16804SVesa Jääskeläinen 		goto ecpoint_cleanup;
54102b16804SVesa Jääskeläinen 
54202b16804SVesa Jääskeläinen 	rc = add_attribute(pub_head, PKCS11_CKA_EC_POINT, ecpoint, dersize);
54302b16804SVesa Jääskeläinen 
54402b16804SVesa Jääskeläinen ecpoint_cleanup:
54502b16804SVesa Jääskeläinen 	TEE_Free(ecpoint);
54602b16804SVesa Jääskeläinen y_cleanup:
54702b16804SVesa Jääskeläinen 	TEE_Free(y_ptr);
54802b16804SVesa Jääskeläinen x_cleanup:
54902b16804SVesa Jääskeläinen 	TEE_Free(x_ptr);
55002b16804SVesa Jääskeläinen out:
55102b16804SVesa Jääskeläinen 	return rc;
55202b16804SVesa Jääskeläinen }
55302b16804SVesa Jääskeläinen 
55402b16804SVesa Jääskeläinen enum pkcs11_rc generate_ec_keys(struct pkcs11_attribute_head *proc_params,
55502b16804SVesa Jääskeläinen 				struct obj_attrs **pub_head,
55602b16804SVesa Jääskeläinen 				struct obj_attrs **priv_head)
55702b16804SVesa Jääskeläinen {
55802b16804SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
55902b16804SVesa Jääskeläinen 	void *a_ptr = NULL;
56002b16804SVesa Jääskeläinen 	uint32_t a_size = 0;
56102b16804SVesa Jääskeläinen 	uint32_t tee_size = 0;
56202b16804SVesa Jääskeläinen 	uint32_t tee_curve = 0;
56302b16804SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
56402b16804SVesa Jääskeläinen 	TEE_Attribute tee_key_attr[1] = { };
56502b16804SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
56602b16804SVesa Jääskeläinen 
56702b16804SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
56802b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
56902b16804SVesa Jääskeläinen 
57002b16804SVesa Jääskeläinen 	if (remove_empty_attribute(pub_head, PKCS11_CKA_EC_POINT) ||
57102b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_VALUE) ||
57202b16804SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EC_PARAMS)) {
57302b16804SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
57402b16804SVesa Jääskeläinen 		trace_attributes("public-key", *pub_head);
57502b16804SVesa Jääskeläinen 		trace_attributes("private-key", *priv_head);
57602b16804SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
57702b16804SVesa Jääskeläinen 	}
57802b16804SVesa Jääskeläinen 
57902b16804SVesa Jääskeläinen 	if (get_attribute_ptr(*pub_head, PKCS11_CKA_EC_PARAMS,
58002b16804SVesa Jääskeläinen 			      &a_ptr, &a_size) || !a_ptr) {
58102b16804SVesa Jääskeläinen 		EMSG("No EC_PARAMS attribute found in public key");
58202b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
58302b16804SVesa Jääskeläinen 	}
58402b16804SVesa Jääskeläinen 
58502b16804SVesa Jääskeläinen 	tee_size = ec_params2tee_keysize(a_ptr, a_size);
58602b16804SVesa Jääskeläinen 	if (!tee_size)
58702b16804SVesa Jääskeläinen 		return PKCS11_CKR_ATTRIBUTE_TYPE_INVALID;
58802b16804SVesa Jääskeläinen 
58902b16804SVesa Jääskeläinen 	tee_curve = ec_params2tee_curve(a_ptr, a_size);
59002b16804SVesa Jääskeläinen 
59102b16804SVesa Jääskeläinen 	TEE_InitValueAttribute(tee_key_attr, TEE_ATTR_ECC_CURVE, tee_curve, 0);
59202b16804SVesa Jääskeläinen 
59302b16804SVesa Jääskeläinen 	/* Create an ECDSA TEE key: will match PKCS11 ECDSA and ECDH */
59402b16804SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_ECDSA_KEYPAIR, tee_size,
59502b16804SVesa Jääskeläinen 					  &tee_obj);
59602b16804SVesa Jääskeläinen 	if (res) {
59702b16804SVesa Jääskeläinen 		EMSG("Transient alloc failed with %#"PRIx32, res);
59802b16804SVesa Jääskeläinen 		return tee2pkcs_error(res);
59902b16804SVesa Jääskeläinen 	}
60002b16804SVesa Jääskeläinen 
60102b16804SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
60202b16804SVesa Jääskeläinen 	if (res) {
60302b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
60402b16804SVesa Jääskeläinen 		goto out;
60502b16804SVesa Jääskeläinen 	}
60602b16804SVesa Jääskeläinen 
60702b16804SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, tee_size, tee_key_attr, 1);
60802b16804SVesa Jääskeläinen 	if (res) {
60902b16804SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
61002b16804SVesa Jääskeläinen 		goto out;
61102b16804SVesa Jääskeläinen 	}
61202b16804SVesa Jääskeläinen 
61302b16804SVesa Jääskeläinen 	/* Private key needs the same EC_PARAMS as used by the public key */
61402b16804SVesa Jääskeläinen 	rc = add_attribute(priv_head, PKCS11_CKA_EC_PARAMS, a_ptr, a_size);
61502b16804SVesa Jääskeläinen 	if (rc)
61602b16804SVesa Jääskeläinen 		goto out;
61702b16804SVesa Jääskeläinen 
61802b16804SVesa Jääskeläinen 	rc = tee2pkcs_ec_attributes(pub_head, priv_head, tee_obj, tee_size);
61902b16804SVesa Jääskeläinen 
62002b16804SVesa Jääskeläinen out:
62102b16804SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
62202b16804SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
62302b16804SVesa Jääskeläinen 
62402b16804SVesa Jääskeläinen 	return rc;
62502b16804SVesa Jääskeläinen }
626fb279d8bSVesa Jääskeläinen 
627fb279d8bSVesa Jääskeläinen size_t ecdsa_get_input_max_byte_size(TEE_OperationHandle op)
628fb279d8bSVesa Jääskeläinen {
629fb279d8bSVesa Jääskeläinen 	TEE_OperationInfo info = { };
630fb279d8bSVesa Jääskeläinen 
631fb279d8bSVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
632fb279d8bSVesa Jääskeläinen 
633fb279d8bSVesa Jääskeläinen 	switch (info.algorithm) {
634fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P192:
635fb279d8bSVesa Jääskeläinen 		return 24;
636fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P224:
637fb279d8bSVesa Jääskeläinen 		return 28;
638fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P256:
639fb279d8bSVesa Jääskeläinen 		return 32;
640fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P384:
641fb279d8bSVesa Jääskeläinen 		return 48;
642fb279d8bSVesa Jääskeläinen 	case TEE_ALG_ECDSA_P521:
643fb279d8bSVesa Jääskeläinen 		return 66;
644fb279d8bSVesa Jääskeläinen 	default:
645fb279d8bSVesa Jääskeläinen 		DMSG("Unexpected ECDSA algorithm %#"PRIx32, info.algorithm);
646fb279d8bSVesa Jääskeläinen 		return 0;
647fb279d8bSVesa Jääskeläinen 	}
648fb279d8bSVesa Jääskeläinen }
649*cc062b46SJorge Ramirez-Ortiz 
650*cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_param_ecdh(struct pkcs11_attribute_head *proc_params,
651*cc062b46SJorge Ramirez-Ortiz 				   void **pub_data, size_t *pub_size)
652*cc062b46SJorge Ramirez-Ortiz {
653*cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
654*cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
655*cc062b46SJorge Ramirez-Ortiz 	uint32_t word = 0;
656*cc062b46SJorge Ramirez-Ortiz 	uint8_t byte = 0;
657*cc062b46SJorge Ramirez-Ortiz 
658*cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
659*cc062b46SJorge Ramirez-Ortiz 
660*cc062b46SJorge Ramirez-Ortiz 	/* Skip KDF */
661*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
662*cc062b46SJorge Ramirez-Ortiz 	if (rc)
663*cc062b46SJorge Ramirez-Ortiz 		return rc;
664*cc062b46SJorge Ramirez-Ortiz 
665*cc062b46SJorge Ramirez-Ortiz 	/* Shared data size, shall be 0 */
666*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
667*cc062b46SJorge Ramirez-Ortiz 	if (rc || word)
668*cc062b46SJorge Ramirez-Ortiz 		return rc;
669*cc062b46SJorge Ramirez-Ortiz 
670*cc062b46SJorge Ramirez-Ortiz 	/* Public data size and content */
671*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &word);
672*cc062b46SJorge Ramirez-Ortiz 	if (rc || !word)
673*cc062b46SJorge Ramirez-Ortiz 		return rc;
674*cc062b46SJorge Ramirez-Ortiz 
675*cc062b46SJorge Ramirez-Ortiz 	*pub_size = word;
676*cc062b46SJorge Ramirez-Ortiz 
677*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get(&args, &byte, sizeof(uint8_t));
678*cc062b46SJorge Ramirez-Ortiz 	if (rc)
679*cc062b46SJorge Ramirez-Ortiz 		return rc;
680*cc062b46SJorge Ramirez-Ortiz 
681*cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x02 && byte != 0x03 && byte != 0x04)
682*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
683*cc062b46SJorge Ramirez-Ortiz 
684*cc062b46SJorge Ramirez-Ortiz 	if (byte != 0x04) {
685*cc062b46SJorge Ramirez-Ortiz 		EMSG("DER compressed public key format not yet supported");
686*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
687*cc062b46SJorge Ramirez-Ortiz 	}
688*cc062b46SJorge Ramirez-Ortiz 
689*cc062b46SJorge Ramirez-Ortiz 	*pub_size -= sizeof(uint8_t);
690*cc062b46SJorge Ramirez-Ortiz 
691*cc062b46SJorge Ramirez-Ortiz 	if (*pub_size >= 0x80) {
692*cc062b46SJorge Ramirez-Ortiz 		EMSG("DER long definitive form not yet supported");
693*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
694*cc062b46SJorge Ramirez-Ortiz 	}
695*cc062b46SJorge Ramirez-Ortiz 
696*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_ptr(&args, pub_data, *pub_size);
697*cc062b46SJorge Ramirez-Ortiz 	if (rc)
698*cc062b46SJorge Ramirez-Ortiz 		return rc;
699*cc062b46SJorge Ramirez-Ortiz 
700*cc062b46SJorge Ramirez-Ortiz 	if (serialargs_remaining_bytes(&args))
701*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_ARGUMENTS_BAD;
702*cc062b46SJorge Ramirez-Ortiz 
703*cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
704*cc062b46SJorge Ramirez-Ortiz }
705*cc062b46SJorge Ramirez-Ortiz 
706*cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc pkcs2tee_algo_ecdh(uint32_t *tee_id,
707*cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_attribute_head *proc_params,
708*cc062b46SJorge Ramirez-Ortiz 				  struct pkcs11_object *obj)
709*cc062b46SJorge Ramirez-Ortiz {
710*cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
711*cc062b46SJorge Ramirez-Ortiz 	struct serialargs args = { };
712*cc062b46SJorge Ramirez-Ortiz 	uint32_t kdf = 0;
713*cc062b46SJorge Ramirez-Ortiz 
714*cc062b46SJorge Ramirez-Ortiz 	serialargs_init(&args, proc_params->data, proc_params->size);
715*cc062b46SJorge Ramirez-Ortiz 
716*cc062b46SJorge Ramirez-Ortiz 	rc = serialargs_get_u32(&args, &kdf);
717*cc062b46SJorge Ramirez-Ortiz 	if (rc)
718*cc062b46SJorge Ramirez-Ortiz 		return rc;
719*cc062b46SJorge Ramirez-Ortiz 
720*cc062b46SJorge Ramirez-Ortiz 	/* Remaining arguments are extracted by pkcs2tee_param_ecdh */
721*cc062b46SJorge Ramirez-Ortiz 	if (kdf != PKCS11_CKD_NULL) {
722*cc062b46SJorge Ramirez-Ortiz 		DMSG("Only support CKD_NULL key derivation for ECDH");
723*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
724*cc062b46SJorge Ramirez-Ortiz 	}
725*cc062b46SJorge Ramirez-Ortiz 
726*cc062b46SJorge Ramirez-Ortiz 	switch (get_object_key_bit_size(obj)) {
727*cc062b46SJorge Ramirez-Ortiz 	case 192:
728*cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P192;
729*cc062b46SJorge Ramirez-Ortiz 		break;
730*cc062b46SJorge Ramirez-Ortiz 	case 224:
731*cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P224;
732*cc062b46SJorge Ramirez-Ortiz 		break;
733*cc062b46SJorge Ramirez-Ortiz 	case 256:
734*cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P256;
735*cc062b46SJorge Ramirez-Ortiz 		break;
736*cc062b46SJorge Ramirez-Ortiz 	case 384:
737*cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P384;
738*cc062b46SJorge Ramirez-Ortiz 		break;
739*cc062b46SJorge Ramirez-Ortiz 	case 521:
740*cc062b46SJorge Ramirez-Ortiz 		*tee_id = TEE_ALG_ECDH_P521;
741*cc062b46SJorge Ramirez-Ortiz 		break;
742*cc062b46SJorge Ramirez-Ortiz 	default:
743*cc062b46SJorge Ramirez-Ortiz 		TEE_Panic(0);
744*cc062b46SJorge Ramirez-Ortiz 		break;
745*cc062b46SJorge Ramirez-Ortiz 	}
746*cc062b46SJorge Ramirez-Ortiz 
747*cc062b46SJorge Ramirez-Ortiz 	return PKCS11_CKR_OK;
748*cc062b46SJorge Ramirez-Ortiz }
749