blob: 9bcb1795f9c46bbe11e77fd5fec916c4a4f281ba [file] [log] [blame]
/*
*
* Copyright 2017-2019 NXP
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @par Description
* Implementation of key association between NXP Secure Element and mbedtls.
*
*****************************************************************************/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_ALT) && SSS_HAVE_ALT_SSS
#include <fsl_sss_util_asn1_der.h>
#include <nxLog_sss.h>
#include <stdio.h>
#include <string.h>
#include "mbedtls/ecdh.h"
#include "mbedtls/version.h"
#if defined(SSS_USE_FTR_FILE)
#include "fsl_sss_ftr.h"
#else
#include "fsl_sss_ftr_default.h"
#endif
#if defined(FLOW_VERBOSE) && FLOW_VERBOSE == 1
#include "sm_printf.h"
#include "sm_types.h"
#endif /* FLOW_VERBOSE */
extern int mbedtls_ecdh_gen_public_o(mbedtls_ecp_group *grp,
mbedtls_mpi *d,
mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
extern int mbedtls_ecdh_compute_shared_o(mbedtls_ecp_group *grp,
mbedtls_mpi *z,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng);
extern int mbedtls_ecdh_get_params_o(mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, mbedtls_ecdh_side side);
int get_header_and_bit_Length(int groupid, int *headerLen, int *bitLen)
{
switch (groupid) {
case MBEDTLS_ECP_DP_SECP192R1:
if (headerLen != NULL)
*headerLen = der_ecc_nistp192_header_len;
if (bitLen != NULL)
*bitLen = 192;
break;
case MBEDTLS_ECP_DP_SECP224R1:
if (headerLen != NULL)
*headerLen = der_ecc_nistp224_header_len;
if (bitLen != NULL)
*bitLen = 224;
break;
case MBEDTLS_ECP_DP_SECP256R1:
if (headerLen != NULL)
*headerLen = der_ecc_nistp256_header_len;
if (bitLen != NULL)
*bitLen = 256;
break;
case MBEDTLS_ECP_DP_SECP384R1:
if (headerLen != NULL)
*headerLen = der_ecc_nistp384_header_len;
if (bitLen != NULL)
*bitLen = 384;
break;
case MBEDTLS_ECP_DP_SECP521R1:
if (headerLen != NULL)
*headerLen = der_ecc_nistp521_header_len;
if (bitLen != NULL)
*bitLen = 521;
break;
case MBEDTLS_ECP_DP_BP256R1:
if (headerLen != NULL)
*headerLen = der_ecc_bp256_header_len;
if (bitLen != NULL)
*bitLen = 256;
break;
case MBEDTLS_ECP_DP_BP384R1:
if (headerLen != NULL)
*headerLen = der_ecc_bp384_header_len;
if (bitLen != NULL)
*bitLen = 384;
break;
case MBEDTLS_ECP_DP_BP512R1:
if (headerLen != NULL)
*headerLen = der_ecc_bp512_header_len;
if (bitLen != NULL)
*bitLen = 512;
break;
case MBEDTLS_ECP_DP_SECP192K1:
if (headerLen != NULL)
*headerLen = der_ecc_192k_header_len;
if (bitLen != NULL)
*bitLen = 192;
break;
case MBEDTLS_ECP_DP_SECP224K1:
if (headerLen != NULL)
*headerLen = der_ecc_224k_header_len;
if (bitLen != NULL)
*bitLen = 224;
break;
case MBEDTLS_ECP_DP_SECP256K1:
if (headerLen != NULL)
*headerLen = der_ecc_256k_header_len;
if (bitLen != NULL)
*bitLen = 256;
break;
case MBEDTLS_ECP_DP_CURVE25519:
if (headerLen != NULL)
*headerLen = 0;
if (bitLen != NULL)
*bitLen = 256;
break;
case MBEDTLS_ECP_DP_CURVE448:
if (headerLen != NULL)
*headerLen = 0;
if (bitLen != NULL)
*bitLen = 448;
break;
default:
LOG_E("get_header_and_bit_Length: Group id not supported");
return 1;
}
return 0;
}
/*
* Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
*/
int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp,
mbedtls_mpi *d,
mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
sss_status_t status = kStatus_SSS_Fail;
uint8_t publickey[256] = {
0,
};
int headerLen = 0;
size_t publickeylen = sizeof(publickey);
size_t publickeyBitLen = publickeylen * 8;
if (grp->pSSSObject == NULL) {
return mbedtls_ecdh_gen_public_o(grp, d, Q, f_rng, p_rng);
}
else if (grp->pSSSObject->objectType == kSSS_KeyPart_Pair &&
(grp->pSSSObject->cipherType == kSSS_CipherType_EC_NIST_P ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_NIST_K ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_BRAINPOOL ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_MONTGOMERY ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_TWISTED_ED)) {
if (get_header_and_bit_Length(grp->id, &headerLen, NULL)) {
return 1;
}
mbedtls_mpi_free(d);
status = sss_key_store_get_key(
grp->pSSSObject->keyStore, grp->pSSSObject, publickey, &publickeylen, &publickeyBitLen);
if (kStatus_SSS_Success == status) {
publickeylen -= headerLen;
return mbedtls_ecp_point_read_binary(grp, Q, &publickey[headerLen], publickeylen);
}
else {
return 1;
}
}
return 1;
}
/*
* Compute shared secret (SEC1 3.3.1)
*/
int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp,
mbedtls_mpi *z,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
int ret = 1;
sss_key_part_t keyType = kSSS_KeyPart_NONE;
sss_cipher_type_t cipherType = kSSS_CipherType_NONE;
int headerLen = 0;
uint8_t OtherPublicKey[256];
size_t OtherPublickeylen = sizeof(OtherPublicKey);
int keyBitLen = 0;
sss_status_t status;
sss_object_t otherPartyKeyObject;
sss_object_t derivedKeyObject;
sss_derive_key_t context;
uint8_t SharedSecret[128];
uint16_t SharedSecretlen = sizeof(SharedSecret);
uint8_t buf[256];
size_t bitLen = 500;
size_t bufByteLen = sizeof(buf);
sss_cipher_type_t OtherPublickeycipherType = kSSS_CipherType_NONE;
if (get_header_and_bit_Length(grp->id, &headerLen, &keyBitLen)) {
return 1;
}
if (grp->pSSSObject == NULL) {
ret = mbedtls_ecdh_compute_shared_o(grp, z, Q, d, f_rng, p_rng);
}
else if (grp->pSSSObject->cipherType == kSSS_CipherType_EC_NIST_P ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_NIST_K ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_BRAINPOOL ||
grp->pSSSObject->cipherType == kSSS_CipherType_EC_MONTGOMERY) {
if (0 == mbedtls_ecp_point_write_binary(grp,
Q,
MBEDTLS_ECP_PF_UNCOMPRESSED,
&OtherPublickeylen,
(OtherPublicKey + headerLen),
sizeof(OtherPublicKey))) {
switch (grp->id) {
case MBEDTLS_ECP_DP_SECP192R1:
memcpy(OtherPublicKey, gecc_der_header_nist192, der_ecc_nistp192_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_nistp192_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_P;
break;
case MBEDTLS_ECP_DP_SECP224R1:
memcpy(OtherPublicKey, gecc_der_header_nist224, der_ecc_nistp224_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_nistp224_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_P;
break;
case MBEDTLS_ECP_DP_SECP256R1:
memcpy(OtherPublicKey, gecc_der_header_nist256, der_ecc_nistp256_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_nistp256_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_P;
break;
case MBEDTLS_ECP_DP_SECP384R1:
memcpy(OtherPublicKey, gecc_der_header_nist384, der_ecc_nistp384_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_nistp384_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_P;
break;
case MBEDTLS_ECP_DP_SECP521R1:
memcpy(OtherPublicKey, gecc_der_header_nist521, der_ecc_nistp521_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_nistp521_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_P;
break;
case MBEDTLS_ECP_DP_BP256R1:
memcpy(OtherPublicKey, gecc_der_header_bp256, der_ecc_bp256_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_bp256_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_BRAINPOOL;
break;
case MBEDTLS_ECP_DP_BP384R1:
memcpy(OtherPublicKey, gecc_der_header_bp384, der_ecc_bp384_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_bp384_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_BRAINPOOL;
break;
case MBEDTLS_ECP_DP_BP512R1:
memcpy(OtherPublicKey, gecc_der_header_bp512, der_ecc_bp512_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_bp512_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_BRAINPOOL;
break;
case MBEDTLS_ECP_DP_SECP192K1:
memcpy(OtherPublicKey, gecc_der_header_192k, der_ecc_192k_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_192k_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_K;
break;
case MBEDTLS_ECP_DP_SECP224K1:
memcpy(OtherPublicKey, gecc_der_header_224k, der_ecc_224k_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_224k_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_K;
break;
case MBEDTLS_ECP_DP_SECP256K1:
memcpy(OtherPublicKey, gecc_der_header_256k, der_ecc_256k_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_256k_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_NIST_K;
break;
case MBEDTLS_ECP_DP_CURVE25519:
memcpy(OtherPublicKey, gecc_der_header_mont_dh_25519, der_ecc_mont_dh_25519_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_mont_dh_25519_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_MONTGOMERY;
break;
case MBEDTLS_ECP_DP_CURVE448:
memcpy(OtherPublicKey, gecc_der_header_mont_dh_448, der_ecc_mont_dh_448_header_len);
OtherPublickeylen = OtherPublickeylen + der_ecc_mont_dh_448_header_len;
OtherPublickeycipherType = kSSS_CipherType_EC_MONTGOMERY;
break;
default:
return 1;
}
do {
//For The derived shared secret init and allocate
status = sss_key_object_init(&derivedKeyObject, grp->hostKs);
if (status != kStatus_SSS_Success) {
printf(
" sss_key_object_init for derivedKeyObject "
"Failed...\n");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
keyType = kSSS_KeyPart_Default;
cipherType = kSSS_CipherType_AES;
status = sss_key_object_allocate_handle(
&derivedKeyObject, (__LINE__), keyType, cipherType, SharedSecretlen, kKeyObject_Mode_Transient);
if (status != kStatus_SSS_Success) {
LOG_E(
" sss_key_object_allocate_handle for derivedKeyObject "
"Failed");
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
break;
}
// SSCP Transient Object for the othe party public key init and allocate
status = sss_key_object_init(&otherPartyKeyObject, grp->hostKs);
if (status != kStatus_SSS_Success) {
LOG_E(
" sss_key_object_init for otherPartyKeyObject "
"Failed");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
status = sss_key_object_allocate_handle(&otherPartyKeyObject,
(__LINE__),
kSSS_KeyPart_Public,
OtherPublickeycipherType,
(sizeof(OtherPublicKey)),
kKeyObject_Mode_Transient);
if (status != kStatus_SSS_Success) {
LOG_E(
" sss_key_object_allocate_handle for "
"otherPartyKeyObject Failed");
ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
break;
}
//setting the other party public key
status = sss_key_store_set_key(
grp->hostKs, &otherPartyKeyObject, OtherPublicKey, OtherPublickeylen, keyBitLen, NULL, 0);
if (status != kStatus_SSS_Success) {
LOG_E(" sss_key_store_set_key for keyPair Failed");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
status = sss_derive_key_context_init(&context,
grp->pSSSObject->keyStore->session,
grp->pSSSObject,
kAlgorithm_SSS_ECDH,
kMode_SSS_ComputeSharedSecret);
if (status != kStatus_SSS_Success) {
printf(" sss_derive_key_context_init Failed...\n");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
status = sss_derive_key_dh(&context, &otherPartyKeyObject, &derivedKeyObject);
if (status != kStatus_SSS_Success) {
printf(" sss_derive_key_dh Failed...\n");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
status = sss_key_store_get_key(grp->hostKs, &derivedKeyObject, buf, &bufByteLen, &bitLen);
if (status != kStatus_SSS_Success) {
printf(" sss_key_store_get_key Failed...\n");
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
break;
}
ret = mbedtls_mpi_read_binary(z, buf, bufByteLen);
} while (0);
sss_key_object_free(&otherPartyKeyObject);
sss_key_object_free(&derivedKeyObject);
}
}
else {
ret = 1; //Failed
}
return (ret);
}
/*
* Get parameters from a keypair
*/
int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, mbedtls_ecdh_side side)
{
int ret;
sss_object_t *backup_type_SSS_Object = ctx->grp.pSSSObject;
sss_key_store_t *backup_type_hostKs = ctx->grp.hostKs;
ret = mbedtls_ecdh_get_params_o(ctx, key, side);
ctx->grp.pSSSObject = backup_type_SSS_Object;
ctx->grp.hostKs = backup_type_hostKs;
return (ret);
}
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx, const mbedtls_ecp_keypair *key, mbedtls_ecdh_side side)
{
return mbedtls_ecdh_get_params(ctx, key, side);
}
#endif
#endif /* defined(MBEDTLS_ECDH_C) && defined(MBEDTLS_ECDH_ALT) */