Skip to content

Commit 56df468

Browse files
Ron EldorRon Eldor
authored andcommitted
Alternative ECDSA and ECDH support
Add support for Alternative ECDSA and ECDH, on the higher level, over CC310. Note that CC generates ECC keys according to FIPS 186, while mbed TLS generates according to RFC 6979 and RFC 4754, which causes test vectors for curve p521 to fail
1 parent 19e2adf commit 56df468

File tree

12 files changed

+1720
-0
lines changed

12 files changed

+1720
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* cc_internal.c
3+
*
4+
* Internal utility functions and definitions,
5+
* used for converting mbedtls types to CC types, and vice versa
6+
*
7+
* Copyright (C) 2018, ARM Limited, All Rights Reserved
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
11+
* not use this file except in compliance with the License.
12+
* You may obtain a copy of the License at
13+
*
14+
* http://www.apache.org/licenses/LICENSE-2.0
15+
*
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*
22+
*/
23+
24+
#include "cc_internal.h"
25+
#include "crys_ecpki_error.h"
26+
#include "crys_ec_mont_edw_error.h"
27+
28+
CRYS_ECPKI_DomainID_t convert_mbedtls_grp_id_to_crys_domain_id( mbedtls_ecp_group_id grp_id )
29+
{
30+
switch( grp_id )
31+
{
32+
case MBEDTLS_ECP_DP_SECP192K1:
33+
return ( CRYS_ECPKI_DomainID_secp192k1 );
34+
case MBEDTLS_ECP_DP_SECP192R1:
35+
return ( CRYS_ECPKI_DomainID_secp192r1 );
36+
case MBEDTLS_ECP_DP_SECP224K1:
37+
return ( CRYS_ECPKI_DomainID_secp224k1 );
38+
case MBEDTLS_ECP_DP_SECP224R1:
39+
return ( CRYS_ECPKI_DomainID_secp224r1 );
40+
case MBEDTLS_ECP_DP_SECP256K1:
41+
return ( CRYS_ECPKI_DomainID_secp256k1 );
42+
case MBEDTLS_ECP_DP_SECP256R1:
43+
return ( CRYS_ECPKI_DomainID_secp256r1 );
44+
case MBEDTLS_ECP_DP_SECP384R1:
45+
return ( CRYS_ECPKI_DomainID_secp384r1 );
46+
case MBEDTLS_ECP_DP_SECP521R1:
47+
return ( CRYS_ECPKI_DomainID_secp521r1 );
48+
default:
49+
return ( CRYS_ECPKI_DomainID_OffMode );
50+
}
51+
52+
}
53+
54+
uint32_t convert_mbedtls_to_cc_rand( void* mbedtls_rnd_ctx, uint16_t outSizeBytes, uint8_t* out_ptr )
55+
{
56+
uint16_t i = 0;
57+
uint8_t temp = 0;
58+
mbedtls_rand_func_container* mbedtls_rand = (mbedtls_rand_func_container*)mbedtls_rnd_ctx;
59+
60+
if( mbedtls_rand->f_rng( mbedtls_rand->ctx, out_ptr, outSizeBytes ) != 0 )
61+
return ( MBEDTLS_ERR_ECP_RANDOM_FAILED );
62+
63+
/*
64+
* CC requires the random data as LE, so reversing the data
65+
* (although this is random, but test vectors are in specific Endianess)
66+
*/
67+
while ( i < ( outSizeBytes / 2 ) )
68+
{
69+
temp = out_ptr[outSizeBytes - 1 - i];
70+
out_ptr[outSizeBytes - 1 - i] = out_ptr[i];
71+
out_ptr[i] = temp;
72+
++i;
73+
}
74+
/*
75+
* CC increases the random data by one, to put the vector in the proper range (1 to n),
76+
* The RFC tests supply a data buffer within range, and in order to generate the proper ephemeral key,
77+
* need to decrease one from this data, before CC increases the data, so the output will be as expected
78+
*/
79+
i = 0;
80+
while( out_ptr[i] == 0 )
81+
{
82+
++i;
83+
}
84+
while( i > 0 )
85+
{
86+
--out_ptr[i];
87+
--i;
88+
}
89+
--out_ptr[0];
90+
return ( 0 );
91+
}
92+
93+
int convert_CrysError_to_mbedtls_err( CRYSError_t Crys_err )
94+
{
95+
switch(Crys_err)
96+
{
97+
case CRYS_OK:
98+
return ( 0 );
99+
100+
case CRYS_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR:
101+
case CRYS_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR:
102+
case CRYS_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR:
103+
case CRYS_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR:
104+
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR:
105+
case CRYS_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR:
106+
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR:
107+
case CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR:
108+
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR:
109+
case CRYS_ECMONT_INVALID_INPUT_POINTER_ERROR:
110+
case CRYS_ECMONT_INVALID_INPUT_SIZE_ERROR:
111+
case CRYS_ECMONT_INVALID_DOMAIN_ID_ERROR:
112+
case CRYS_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR:
113+
case CRYS_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR:
114+
case CRYS_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR:
115+
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
116+
case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
117+
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
118+
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
119+
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR:
120+
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR:
121+
case CRYS_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR:
122+
case CRYS_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR:
123+
case CRYS_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR:
124+
case CRYS_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR:
125+
case CRYS_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR:
126+
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR:
127+
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR:
128+
case CRYS_ECPKI_INVALID_RND_CTX_PTR_ERROR:
129+
case CRYS_ECPKI_INVALID_RND_FUNC_PTR_ERROR:
130+
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR:
131+
return ( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
132+
133+
case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
134+
return ( MBEDTLS_ERR_ECP_VERIFY_FAILED );
135+
136+
case CRYS_ECMONT_IS_NOT_SUPPORTED:
137+
case CRYS_ECEDW_IS_NOT_SUPPORTED:
138+
return ( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
139+
140+
case CRYS_ECEDW_RND_GEN_VECTOR_FUNC_ERROR:
141+
return ( MBEDTLS_ERR_ECP_RANDOM_FAILED );
142+
143+
case CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR:
144+
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR:
145+
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR:
146+
return ( MBEDTLS_ERR_ECP_INVALID_KEY );
147+
148+
default:
149+
return ( MBEDTLS_ERR_ECP_HW_ACCEL_FAILED );
150+
}
151+
152+
153+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* cc_internal.h
3+
*
4+
* Internal utility functions and definitions,
5+
* used for converting mbedtls types to CC types, and vice versa
6+
*
7+
* Copyright (C) 2018, ARM Limited, All Rights Reserved
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
11+
* not use this file except in compliance with the License.
12+
* You may obtain a copy of the License at
13+
*
14+
* http://www.apache.org/licenses/LICENSE-2.0
15+
*
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*
22+
*/
23+
24+
#ifndef __CC_INTERNAL_H__
25+
#define __CC_INTERNAL_H__
26+
#include "crys_ecpki_types.h"
27+
#include "crys_ec_mont_api.h"
28+
#include "mbedtls/ecp.h"
29+
#include <stddef.h>
30+
#include <stdint.h>
31+
32+
#define CURVE_25519_KEY_SIZE 32
33+
34+
#ifdef __cplusplus
35+
extern "C" {
36+
#endif
37+
38+
#define MAX_KEY_SIZE_IN_BYTES ( ( CRYS_ECPKI_MODUL_MAX_LENGTH_IN_WORDS ) * SASI_32BIT_WORD_SIZE)
39+
40+
/* ECC utility functions and structures*/
41+
typedef struct cc_ecc_ws_keygen_params{
42+
CRYS_ECPKI_UserPublKey_t pubKey;
43+
CRYS_ECPKI_UserPrivKey_t privKey;
44+
CRYS_ECPKI_KG_TempData_t kgTempData;
45+
} cc_ecc_ws_keygen_params_t;
46+
47+
typedef struct cc_ecc_ws_comp_shared_params{
48+
CRYS_ECPKI_UserPublKey_t pubKey;
49+
CRYS_ECPKI_UserPrivKey_t privKey;
50+
CRYS_ECDH_TempData_t ecdhTempData;
51+
} cc_ecc_ws_comp_shared_params_t;
52+
53+
typedef struct cc_ecc_ws_verify_params{
54+
CRYS_ECPKI_UserPublKey_t pubKey;
55+
CRYS_ECDSA_VerifyUserContext_t verifyContext;
56+
} cc_ecc_ws_verify_params_t;
57+
58+
typedef struct cc_ecc_ws_sign_params{
59+
CRYS_ECPKI_UserPrivKey_t privKey;
60+
CRYS_ECDSA_SignUserContext_t signContext;
61+
} cc_ecc_ws_sign_params_t;
62+
63+
typedef struct cc_ecc_25519_keygen_params{
64+
uint8_t pubKey[CURVE_25519_KEY_SIZE];
65+
uint8_t privKey[CURVE_25519_KEY_SIZE];
66+
CRYS_ECMONT_TempBuff_t kgTempData;
67+
} cc_ecc_25519_keygen_params_t;
68+
69+
typedef cc_ecc_25519_keygen_params_t cc_ecc_25519_comp_shared_params_t;
70+
71+
/**
72+
* \brief This function converts mbedtls type mbedtls_ecp_group_id
73+
* to Cryptocell type CRYS_ECPKI_DomainID_t
74+
*
75+
* \param grp_id The mbedtls mbedtls_ecp_group_id to convert
76+
*
77+
* \return \c The corresponding CRYS_ECPKI_DomainID_t.
78+
* CRYS_ECPKI_DomainID_OffMode if not recognized.
79+
*/
80+
CRYS_ECPKI_DomainID_t convert_mbedtls_grp_id_to_crys_domain_id( mbedtls_ecp_group_id grp_id );
81+
82+
/* f_rng conversion from mbedtls type to cc type*/
83+
typedef struct
84+
{
85+
int (*f_rng)( void* ctx, unsigned char* output, size_t outSizeBytes );
86+
void* ctx;
87+
88+
}mbedtls_rand_func_container;
89+
90+
/**
91+
* \brief This function converts mbedtls f_rng type to
92+
* Cryptocell f_rng type(SaSiRndGenerateVectWorkFunc_t)
93+
*
94+
* Note: The Mbed TLS type f_rng signature is:
95+
* int (*f_rng)( void* ctx, unsigned char* output, size_t outSizeBytes );
96+
* while CC f_rng signature is:
97+
* uint32_t (*SaSiRndGenerateVectWorkFunc_t)(
98+
* void *rndState_ptr,
99+
* uint16_t outSizeBytes,
100+
* uint8_t *out_ptr)
101+
*
102+
* so the Mbed TLS f_rng can't be sent as is to the CC API.
103+
*
104+
* In addition, this function manipulates the different random data,
105+
* to adjust between the way Cryptocell reads the random data. This is done for
106+
* different standard tests to pass.
107+
*
108+
*
109+
* \param grp_id The mbedtls mbedtls_ecp_group_id to convert
110+
*
111+
* \return \c The corresponding CRYS_ECPKI_DomainID_t.
112+
* CRYS_ECPKI_DomainID_OffMode if not recognized.
113+
*/
114+
115+
uint32_t convert_mbedtls_to_cc_rand( void* mbedtls_rand, uint16_t outSizeBytes, uint8_t* out_ptr );
116+
117+
/**
118+
* \brief This function convertsCryptocell error
119+
* Mbed TLS related error.
120+
*
121+
*
122+
* \return \c The corresponding Mbed TLS error,
123+
* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED as default, if none found
124+
*/
125+
int convert_CrysError_to_mbedtls_err( CRYSError_t Crys_err );
126+
127+
#ifdef __cplusplus
128+
}
129+
#endif
130+
131+
#endif /* __CC_INTERNAL_H__ */
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* cc_rand.h
3+
*
4+
* Copyright (C) 2018, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*
19+
*/
20+
#ifndef __CC_RAND_H__
21+
#define __CC_RAND_H__
22+
#include <stddef.h>
23+
#include <stdint.h>
24+
25+
typedef struct
26+
{
27+
int (*f_rng)(void* ctx, unsigned char* output, size_t outSizeBytes);
28+
void* ctx;
29+
30+
}mbedtls_rand_func_container;
31+
32+
33+
uint32_t mbedtls_to_cc_rand_func( void *mbedtls_rnd_ctx, uint16_t outSizeBytes, uint8_t *out_ptr )
34+
{
35+
uint16_t i = 0;
36+
uint8_t temp = 0;
37+
mbedtls_rand_func_container* mbedtls_rand = (mbedtls_rand_func_container*)mbedtls_rnd_ctx;
38+
uint32_t ret = mbedtls_rand->f_rng( mbedtls_rand->ctx, out_ptr, outSizeBytes );
39+
if( ret != 0 )
40+
return ret;
41+
42+
/*
43+
* CC requires the random data as LE, so reversing the data
44+
* (although this is random, but test vectors are in specific Endianess)
45+
*/
46+
while ( i < ( outSizeBytes / 2 ) )
47+
{
48+
temp = out_ptr[outSizeBytes - 1 - i];
49+
out_ptr[outSizeBytes - 1 - i] = out_ptr[i];
50+
out_ptr[i] = temp;
51+
++i;
52+
}
53+
/*
54+
* CC increases the random data by one, to put the vector in the proper range (1 to n),
55+
* The RFC tests supply a data buffer within range, and in order to generate the proper ephemeral key,
56+
* need to decrease one from this data, before CC increases the data, so the output will be as expected
57+
*/
58+
i = 0;
59+
while( out_ptr[i] == 0 )
60+
{
61+
++i;
62+
}
63+
while( i > 0 )
64+
{
65+
--out_ptr[i];
66+
--i;
67+
}
68+
--out_ptr[0];
69+
return ret;
70+
}
71+
72+
73+
#endif/* __CC_RAND_H__ */

0 commit comments

Comments
 (0)