const bool FrostIdentity::FromPublicKey(const std::string &publickey)
{
	std::vector<std::string> keyparts;
	std::vector<unsigned char> edata;
	std::vector<unsigned char> ndata;

	mbedtls_rsa_free(&m_rsa);
	mbedtls_rsa_init(&m_rsa,MBEDTLS_RSA_PKCS_V21,MBEDTLS_MD_SHA1);

	StringFunctions::Split(publickey,":",keyparts);

	if(keyparts.size()==2)
	{
		Base64::Decode(keyparts[0],edata);
		Base64::Decode(keyparts[1],ndata);

		mbedtls_mpi_init(&m_rsa.N);
		mbedtls_mpi_init(&m_rsa.E);
		mbedtls_mpi_read_binary(&m_rsa.N,&ndata[0],ndata.size());
		mbedtls_mpi_read_binary(&m_rsa.E,&edata[0],edata.size());

		m_publickey=publickey;

		return true;
	}
	else
	{
		return false;
	}
}
Exemple #2
0
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
	mbedtls_ecp_keypair keypair;
	mbedtls_mpi r;
	mbedtls_mpi s;
	mbedtls_md_type_t mdType;
	const mbedtls_md_info_t *pmdInfo;
	byte rgbDigest[MBEDTLS_MD_MAX_SIZE];
	cn_cbor * pSig;
	bool result = false;

	mbedtls_ecp_keypair_init(&keypair);
	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn;

	switch(cbitDigest)
	{
	case 256:
		mdType = MBEDTLS_MD_SHA256;
		break;

	case 384:
		mdType = MBEDTLS_MD_SHA384;
		break;

	case 512:
		mdType = MBEDTLS_MD_SHA512;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	pmdInfo = mbedtls_md_info_from_type(mdType);
	CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION((pSig != NULL) && (pSig->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);

	CHECK_CONDITION(mbedtls_mpi_read_binary( &r, pSig->v.bytes, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(mbedtls_mpi_read_binary( &s, pSig->v.bytes + pSig->length / 2, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY);
	CHECK_CONDITION(mbedtls_ecdsa_verify(&keypair.grp, rgbDigest, mbedtls_md_get_size(pmdInfo), &keypair.Q, &r, &s) == 0, COSE_ERR_CRYPTO_FAIL);

	result = true;

errorReturn:
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	mbedtls_ecp_keypair_free(&keypair);
	return result;
}
Exemple #3
0
result_t X509Cert::get_serial(exlib::string &retVal)
{
    mbedtls_x509_crt *crt = get_crt();
    if (!crt)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    int32_t ret;
    mbedtls_mpi serial;

    mbedtls_mpi_init(&serial);
    ret = mbedtls_mpi_read_binary(&serial, crt->serial.p, crt->serial.len);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    retVal.resize(8192);
    size_t sz = retVal.length();

    ret = mbedtls_mpi_write_string(&serial, 10, &retVal[0], sz, &sz);
    mbedtls_mpi_free(&serial);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    retVal.resize(sz - 1);

    return 0;
}
Exemple #4
0
int dslink_handshake_read_key_pair(mbedtls_ecdh_context *ctx, char *buf) {
    mbedtls_ecdh_init(ctx);
    dslink_handshake_get_group(&ctx->grp);
    char *q = strchr(buf, ' ');
    if (!q || *(q + 1) == '\0') {
        errno = 0;
        return DSLINK_CRYPT_KEY_DECODE_ERR;
    }

    size_t len = (q - buf);
    unsigned char dec[90];
    size_t decLen = 0;
    if (dslink_base64_url_decode(dec, sizeof(dec), &decLen,
                                 (unsigned char *) buf, len) != 0) {
        return DSLINK_CRYPT_BASE64_URL_DECODE_ERR;
    }

    if ((errno = mbedtls_mpi_read_binary(&ctx->d, dec, decLen)) != 0) {
        return DSLINK_CRYPT_KEY_DECODE_ERR;
    }

    len = strlen(buf) - len - 1;
    if (dslink_base64_url_decode(dec, sizeof(dec), &decLen,
                                 (unsigned char *) (q + 1), len) != 0) {
        return DSLINK_CRYPT_BASE64_URL_DECODE_ERR;
    }

    if ((errno = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q,
                                               dec, decLen)) != 0) {
        return DSLINK_CRYPT_KEY_DECODE_ERR;
    }

    return 0;
}
Exemple #5
0
/* read */
static int unsigned_read(void *a, unsigned char *b, unsigned long len)
{
	int res = mbedtls_mpi_read_binary(a, b, len);

	if (res == MBEDTLS_ERR_MPI_ALLOC_FAILED)
		return CRYPT_MEM;
	if (res)
		return CRYPT_ERROR;

	return CRYPT_OK;
}
int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n)
{
    mbedtls_rsa_context *rsa = NULL;
    const mbedtls_pk_info_t *pk_info = NULL;
    int rc;

    key->rsa = malloc(sizeof(mbedtls_pk_context));
    if (key->rsa == NULL) {
        return SSH_ERROR;
    }

    mbedtls_pk_init(key->rsa);
    pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
    mbedtls_pk_setup(key->rsa, pk_info);

    rc = mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA);
    if (rc == 0) {
        goto fail;
    }

    rsa = mbedtls_pk_rsa(*key->rsa);
    rc = mbedtls_mpi_read_binary(&rsa->N, ssh_string_data(n),
                                 ssh_string_len(n));
    if (rc != 0) {
        goto fail;
    }
    rc = mbedtls_mpi_read_binary(&rsa->E, ssh_string_data(e),
                                 ssh_string_len(e));
    if (rc != 0) {
        goto fail;
    }

    rsa->len = (mbedtls_mpi_bitlen(&rsa->N) + 7) >> 3;

    return SSH_OK;

fail:
    mbedtls_pk_free(key->rsa);
    SAFE_FREE(key->rsa);
    return SSH_ERROR;
}
Exemple #7
0
/*
 * Import the peer's public value G^Y
 */
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
                     const unsigned char *input, size_t ilen )
{
    int ret;

    if( ctx == NULL || ilen < 1 || ilen > ctx->len )
        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );

    if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
        return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );

    return( 0 );
}
Exemple #8
0
int mbedtls_asn1_get_mpi( unsigned char **p,
                  const unsigned char *end,
                  mbedtls_mpi *X )
{
    int ret;
    size_t len;

    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
        return( ret );

    ret = mbedtls_mpi_read_binary( X, *p, len );

    *p += len;

    return( ret );
}
Exemple #9
0
/*
 * Derive a suitable integer for group grp from a buffer of length len
 * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
 */
static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
                       const unsigned char *buf, size_t blen )
{
    int ret;
    size_t n_size = ( grp->nbits + 7 ) / 8;
    size_t use_size = blen > n_size ? n_size : blen;

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
    if( use_size * 8 > grp->nbits )
        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );

    /* While at it, reduce modulo N */
    if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );

cleanup:
    return( ret );
}
TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt *dest,
					    const uint8_t *buffer,
					    uint32_t bufferLen, int32_t sign)
{
	TEE_Result res;
	mbedtls_mpi mpi_dest;

	get_mpi(&mpi_dest, dest);

	if (mbedtls_mpi_read_binary(&mpi_dest,  buffer, bufferLen))
		res = TEE_ERROR_OVERFLOW;
	else
		res = TEE_SUCCESS;

	if (sign < 0)
		mpi_dest.s = -1;

	put_mpi(&mpi_dest);

	return res;
}
Exemple #11
0
/*
 * Do an RSA public key operation
 */
int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
                const unsigned char *input,
                unsigned char *output )
{
    int ret;
    size_t olen;
    mbedtls_mpi T;

    mbedtls_mpi_init( &T );

#if defined(MBEDTLS_THREADING_C)
    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
        return( ret );
#endif

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );

    if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
        goto cleanup;
    }

    olen = ctx->len;
    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );

cleanup:
#if defined(MBEDTLS_THREADING_C)
    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif

    mbedtls_mpi_free( &T );

    if( ret != 0 )
        return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );

    return( 0 );
}
Exemple #12
0
/*
 * helper to validate the mbedtls_mpi size and import it
 */
static int dhm_read_bignum( mbedtls_mpi *X,
                            unsigned char **p,
                            const unsigned char *end )
{
    int ret, n;

    if( end - *p < 2 )
        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );

    n = ( (*p)[0] << 8 ) | (*p)[1];
    (*p) += 2;

    if( (int)( end - *p ) < n )
        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );

    if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
        return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );

    (*p) += n;

    return( 0 );
}
Exemple #13
0
TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
					    struct ecc_public_key *public_key,
					    void *secret,
					    unsigned long *secret_len)
{
	TEE_Result res = TEE_SUCCESS;
	int lmd_res = 0;
	uint8_t one[1] = { 1 };
	mbedtls_ecdh_context ecdh;
	size_t out_len = 0;

	memset(&ecdh, 0, sizeof(ecdh));
	mbedtls_ecdh_init(&ecdh);
	lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve);
	if (lmd_res != 0) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	ecdh.d = *(mbedtls_mpi *)private_key->d;
	ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
	ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
	mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));

	lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
					   *secret_len, mbd_rand, NULL);
	if (lmd_res != 0) {
		res = get_tee_result(lmd_res);
		goto out;
	}
	*secret_len = out_len;
out:
	/* Reset mpi to skip freeing here, those mpis will be freed with key */
	mbedtls_mpi_init(&ecdh.d);
	mbedtls_mpi_init(&ecdh.Qp.X);
	mbedtls_mpi_init(&ecdh.Qp.Y);
	mbedtls_ecdh_free(&ecdh);
	return res;
}
Exemple #14
0
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
    int ret = 0;
    CRYSError_t CrysRet = CRYS_OK;
    void* pHeap = NULL;
    size_t heapSize = 0;
    uint32_t key_size = 2*MAX_KEY_SIZE_IN_BYTES + 1;
    const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( gid ) );
    mbedtls_rand_func_container cc_rand = { f_rng, p_rng };


    if ( pDomain )
    {
        uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};

        cc_ecc_ws_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof(cc_ecc_ws_keygen_params_t) );
        if ( kgParams == NULL )
            return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );

        pHeap = kgParams;
        heapSize = sizeof(cc_ecc_ws_keygen_params_t);

        CrysRet =  CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand, pDomain,
                                          &kgParams->privKey, &kgParams->pubKey,
                                          &kgParams->kgTempData, NULL );
        if ( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            goto cleanup;
        }

        MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, gid ) );

        CrysRet = CRYS_ECPKI_ExportPublKey( &kgParams->pubKey, CRYS_EC_PointUncompressed, temp_buf,  &key_size );
        if ( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            goto cleanup;
        }

        ret = mbedtls_ecp_point_read_binary( &ctx->grp, &ctx->Q, temp_buf, key_size );
        if ( ret != 0 )
            goto cleanup;

        memset ( temp_buf, 0 , sizeof(temp_buf) );

        CrysRet = CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (ctx->grp.nbits+7)/8,
                                                               kgParams->privKey.PrivKeyDbBuff,
                                                               4*((((ctx->grp.nbits+7)/8)+3)/4) );
        if ( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
            goto cleanup;
        }

        ret = mbedtls_mpi_read_binary( &ctx->d, temp_buf, (ctx->grp.nbits+7)/8 );
        mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
        if ( ret != 0 )
        {
            goto cleanup;
        }
    }
    else
        ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;


cleanup:
    if ( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free ( pHeap );
    }
    return ( ret );
}
Exemple #15
0
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;
    void* pHeap = NULL;
    size_t   heapSize = 0;

    size_t   public_key_size = (grp->nbits+7)/8 ;
    const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );
    uint32_t secret_size =  ( ( grp->nbits + 7 ) / 8 ) ;
    const uint32_t secret_size_in_heap = secret_size;
    uint8_t* secret = mbedtls_calloc( 1, secret_size_in_heap );
    if ( secret == NULL )
        return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );

    /*
     * Make sure Q is a valid pubkey before using it
     */
    MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
    if ( pDomain )
    {
        uint8_t  temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
        cc_ecc_ws_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_ws_comp_shared_params_t) );

        if ( ecdhParams == NULL )
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        pHeap = ecdhParams;
        heapSize = sizeof(cc_ecc_ws_comp_shared_params_t);


        MBEDTLS_MPI_CHK( mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
                                                &public_key_size, temp_buf, sizeof(temp_buf) ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPublKey( pDomain, temp_buf, public_key_size,
                                                                         &ecdhParams->pubKey ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }

        memset ( temp_buf, 0, sizeof(temp_buf)  );

        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_BuildPrivKey( pDomain,
                                                                         temp_buf,
                                                                         mbedtls_mpi_size( d ),
                                                                         &ecdhParams->privKey ) );
        mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECDH_SVDP_DH( &ecdhParams->pubKey, &ecdhParams->privKey,
                                                                   secret, &secret_size,
                                                                   &ecdhParams->ecdhTempData ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }
    }
    else if ( grp->id ==  MBEDTLS_ECP_DP_CURVE25519 )
    {
        cc_ecc_25519_comp_shared_params_t* ecdhParams =  mbedtls_calloc( 1, sizeof(cc_ecc_25519_comp_shared_params_t) );
        if ( ecdhParams == NULL )
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        pHeap = ecdhParams;
        heapSize = sizeof(cc_ecc_25519_comp_shared_params_t);


        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, ecdhParams->privKey, mbedtls_mpi_size( d ) ) ) ;
        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &Q->X, ecdhParams->pubKey, public_key_size ) );

        ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_Scalarmult( secret, ( size_t* )&secret_size,
                                                                        ecdhParams->privKey, CURVE_25519_KEY_SIZE ,
                                                                        ecdhParams->pubKey, CURVE_25519_KEY_SIZE ,
                                                                        &ecdhParams->kgTempData ) );
        if ( ret != 0 )
        {
            goto cleanup;
        }
    }
    else
    {
        ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
        goto cleanup;
    }

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( z, secret, secret_size ) );

cleanup:

    if ( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free ( pHeap );
    }

    if ( secret )
    {
        mbedtls_zeroize( secret, secret_size_in_heap );
        mbedtls_free ( secret );
    }

    return ( ret );
}
Exemple #16
0
TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
				     const uint8_t *msg, size_t msg_len,
				     const uint8_t *sig, size_t sig_len)
{
	TEE_Result res = TEE_SUCCESS;
	int lmd_res = 0;
	mbedtls_ecdsa_context ecdsa;
	size_t key_size_bytes, key_size_bits = 0;
	uint8_t one[1] = { 1 };
	mbedtls_mpi r;
	mbedtls_mpi s;

	memset(&ecdsa, 0, sizeof(ecdsa));
	memset(&r, 0, sizeof(r));
	memset(&s, 0, sizeof(s));

	if (algo == 0)
		return TEE_ERROR_BAD_PARAMETERS;

	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	mbedtls_ecdsa_init(&ecdsa);

	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
	if (lmd_res != 0) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));

	res = ecc_get_keysize(key->curve, algo,
			      &key_size_bytes, &key_size_bits);
	if (res != TEE_SUCCESS) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* check keysize vs sig_len */
	if ((key_size_bytes * 2) != sig_len) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);

	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
				       &r, &s);
	if (lmd_res != 0) {
		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
		res = get_tee_result(lmd_res);
	}
out:
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	/* Reset mpi to skip freeing here, those mpis will be freed with key */
	mbedtls_mpi_init(&ecdsa.Q.X);
	mbedtls_mpi_init(&ecdsa.Q.Y);
	mbedtls_ecdsa_free(&ecdsa);
	return res;
}
Exemple #17
0
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 )
{
      int ret = 0;
      void* pHeap = NULL;
      size_t   heapSize = 0;

      uint32_t public_key_size = (2 * MAX_KEY_SIZE_IN_BYTES + 1);
      const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id(  grp->id ) );
      mbedtls_rand_func_container cc_rand = { f_rng, p_rng };

      if ( pDomain )
      {
          uint8_t temp_buf[ 2 * MAX_KEY_SIZE_IN_BYTES + 1 ] = {0};
          cc_ecc_ws_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof( cc_ecc_ws_keygen_params_t ) );

          if ( kgParams == NULL )
              return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
          pHeap = kgParams;
          heapSize = sizeof( cc_ecc_ws_keygen_params_t );

          ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_GenKeyPair( &cc_rand, convert_mbedtls_to_cc_rand,
                                       pDomain, &kgParams->privKey,
                                       &kgParams->pubKey,
                                       &kgParams->kgTempData, NULL ) );
          if( ret != 0 )
          {
              goto cleanup;
          }

          ret = convert_CrysError_to_mbedtls_err( CRYS_ECPKI_ExportPublKey( &kgParams->pubKey,
                                         CRYS_EC_PointUncompressed,temp_buf,  &public_key_size ) );
          if( ret != 0 )
          {
              goto cleanup;
          }


          MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( grp, Q, temp_buf, public_key_size ) );
          memset ( temp_buf, 0 , sizeof(temp_buf) );

          ret = convert_CrysError_to_mbedtls_err( CRYS_COMMON_ConvertLswMswWordsToMsbLsbBytes( temp_buf, (grp->nbits+7)/8,
                                                            kgParams->privKey.PrivKeyDbBuff,
                                                            4*((((grp->nbits+7)/8)+3)/4) ) );
          if( ret != 0 )
          {
              mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
              goto cleanup;
          }

          MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary( d, temp_buf, (grp->nbits+7)/8 ) );
          mbedtls_zeroize( temp_buf, sizeof( temp_buf ) );
      }

      /* if CRYS_ECPKI_GetEcDomain returns NULL, then the given curve is either Montgomery 25519
       * or another curve which is not supported by CC310*/
      else if ( grp->id ==  MBEDTLS_ECP_DP_CURVE25519 )
      {
          size_t priv_key_size =  public_key_size = CURVE_25519_KEY_SIZE ;

          cc_ecc_25519_keygen_params_t* kgParams =  mbedtls_calloc( 1, sizeof(cc_ecc_25519_keygen_params_t) );

          if ( kgParams == NULL )
              return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
          pHeap = ( uint8_t* )kgParams;
          heapSize = sizeof(cc_ecc_25519_keygen_params_t);

          ret = convert_CrysError_to_mbedtls_err( CRYS_ECMONT_KeyPair( kgParams->pubKey, ( size_t* )&public_key_size, kgParams->privKey,
                                    &priv_key_size, &cc_rand, convert_mbedtls_to_cc_rand,
                                    &kgParams->kgTempData ) );
          if( ret != 0 )
          {
              goto cleanup;
          }

          MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, kgParams->privKey, priv_key_size ) );
          MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(  &Q->X, kgParams->pubKey, public_key_size ) );
          MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Q->Z, 1 ) );
      }
      else
          ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;

cleanup:

    if ( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free( pHeap );
    }

    return ( ret );
}
Exemple #18
0
int main( int argc, char *argv[] )
{
    int ret;
    mbedtls_ecdh_context ctx_cli, ctx_srv;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    unsigned char cli_to_srv[32], srv_to_cli[32];
    const char pers[] = "ecdh";
    ((void) argc);
    ((void) argv);

    mbedtls_ecdh_init( &ctx_cli );
    mbedtls_ecdh_init( &ctx_srv );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    /*
     * Initialize random number generation
     */
    mbedtls_printf( "  . Seeding the random number generator..." );
    fflush( stdout );

    mbedtls_entropy_init( &entropy );
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers,
                               sizeof pers ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * Client: inialize context and generate keypair
     */
    mbedtls_printf( "  . Setting up client context..." );
    fflush( stdout );

    ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecp_group_load returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q,
                                   mbedtls_ctr_drbg_random, &ctr_drbg );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdh_gen_public returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_write_binary returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * Server: initialize context and generate keypair
     */
    mbedtls_printf( "  . Setting up server context..." );
    fflush( stdout );

    ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecp_group_load returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q,
                                   mbedtls_ctr_drbg_random, &ctr_drbg );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdh_gen_public returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_write_binary returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * Server: read peer's key and generate shared secret
     */
    mbedtls_printf( "  . Server reading client key and computing secret..." );
    fflush( stdout );

    ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_lset returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_binary returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z,
                                       &ctx_srv.Qp, &ctx_srv.d,
                                       mbedtls_ctr_drbg_random, &ctr_drbg );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * Client: read peer's key and generate shared secret
     */
    mbedtls_printf( "  . Client reading server key and computing secret..." );
    fflush( stdout );

    ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_lset returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_binary returned %d\n", ret );
        goto exit;
    }

    ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z,
                                       &ctx_cli.Qp, &ctx_cli.d,
                                       mbedtls_ctr_drbg_random, &ctr_drbg );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /*
     * Verification: are the computed secret equal?
     */
    mbedtls_printf( "  . Checking if both computed secrets are equal..." );
    fflush( stdout );

    ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ecdh_compute_shared returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );


exit:

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    mbedtls_ecdh_free( &ctx_srv );
    mbedtls_ecdh_free( &ctx_cli );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

    return( ret != 0 );
}
Exemple #19
0
bool ECKey_From(const cn_cbor * pKey, mbedtls_ecp_keypair *keypair, cose_errback * perr)
{
	byte  rgbKey[MBEDTLS_ECP_MAX_PT_LEN];
	int cbKey;
	int cbGroup;
	const cn_cbor * p;
	mbedtls_ecp_group_id groupId;

	p = cn_cbor_mapget_int(pKey, COSE_Key_Type);
	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
	if(p->type == CN_CBOR_UINT) {
		CHECK_CONDITION(p->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER);
	}
	else {
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Curve);
	CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_UINT), COSE_ERR_INVALID_PARAMETER);

	switch (p->v.uint) {
	case 1: // P-256
		groupId = MBEDTLS_ECP_DP_SECP256R1;
		break;

	case 2: // P-384
		groupId = MBEDTLS_ECP_DP_SECP384R1;
		break;

	case 3: // P-521
		groupId = MBEDTLS_ECP_DP_SECP521R1;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	CHECK_CONDITION(mbedtls_ecp_group_load(&keypair->grp, groupId) == 0, COSE_ERR_INVALID_PARAMETER);
	cbGroup = (keypair->grp.nbits + 7) / 8;

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_X);
	CHECK_CONDITION((p != NULL) && (p->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER);
	memcpy(rgbKey+1, p->v.str, p->length);
	

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Y);
	CHECK_CONDITION((p != NULL), COSE_ERR_INVALID_PARAMETER);
	if (p->type == CN_CBOR_BYTES) {
		rgbKey[0] = 0x04;
		cbKey = cbGroup * 2 + 1;
		CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER);
		memcpy(rgbKey + p->length + 1, p->v.str, p->length);
	}
	else if (p->type == CN_CBOR_TRUE) {
		cbKey = cbGroup + 1;
		rgbKey[0] = 0x03;
	}
	else if (p->type == CN_CBOR_FALSE) {
		cbKey = cbGroup + 1;
		rgbKey[0] = 0x02;
	}
	else FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);

	CHECK_CONDITION(mbedtls_ecp_point_read_binary(&keypair->grp, &keypair->Q, rgbKey, cbKey) == 0, COSE_ERR_INVALID_PARAMETER);

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_d);
	if (p != NULL) {
		CHECK_CONDITION(p->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION(mbedtls_mpi_read_binary( &keypair->d, p->v.bytes, p->length) == 0, COSE_ERR_CRYPTO_FAIL);
	}
	return true;

errorReturn:
	return false;
}
Exemple #20
0
/*
 * Do an RSA private key operation
 */
int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
                 int (*f_rng)(void *, unsigned char *, size_t),
                 void *p_rng,
                 const unsigned char *input,
                 unsigned char *output )
{
    int ret;
    size_t olen;
    mbedtls_mpi T, T1, T2;

    /* Make sure we have private key info, prevent possible misuse */
    if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL )
        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

    mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );

#if defined(MBEDTLS_THREADING_C)
    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
        return( ret );
#endif

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
    if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
        goto cleanup;
    }

    if( f_rng != NULL )
    {
        /*
         * Blinding
         * T = T * Vi mod N
         */
        MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
    }

#if defined(MBEDTLS_RSA_NO_CRT)
    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
#else
    /*
     * faster decryption using the CRT
     *
     * T1 = input ^ dP mod P
     * T2 = input ^ dQ mod Q
     */
    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );

    /*
     * T = (T1 - T2) * (Q^-1 mod P) mod P
     */
    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );

    /*
     * T = T2 + T * Q
     */
    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
#endif /* MBEDTLS_RSA_NO_CRT */

    if( f_rng != NULL )
    {
        /*
         * Unblind
         * T = T * Vf mod N
         */
        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
    }

    olen = ctx->len;
    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );

cleanup:
#if defined(MBEDTLS_THREADING_C)
    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif

    mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );

    if( ret != 0 )
        return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );

    return( 0 );
}
Exemple #21
0
/*
 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
 * WARNING: the resulting group should only be used with
 * pk_group_id_from_specified(), since its base point may not be set correctly
 * if it was encoded compressed.
 *
 *  SpecifiedECDomain ::= SEQUENCE {
 *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
 *      fieldID FieldID {{FieldTypes}},
 *      curve Curve,
 *      base ECPoint,
 *      order INTEGER,
 *      cofactor INTEGER OPTIONAL,
 *      hash HashAlgorithm OPTIONAL,
 *      ...
 *  }
 *
 * We only support prime-field as field type, and ignore hash and cofactor.
 */
static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
{
    int ret;
    unsigned char *p = params->p;
    const unsigned char * const end = params->p + params->len;
    const unsigned char *end_field, *end_curve;
    size_t len;
    int ver;

    /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
    if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ver < 1 || ver > 3 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );

    /*
     * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
     *       fieldType FIELD-ID.&id({IOSet}),
     *       parameters FIELD-ID.&Type({IOSet}{@fieldType})
     * }
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
        return( ret );

    end_field = p + len;

    /*
     * FIELD-ID ::= TYPE-IDENTIFIER
     * FieldTypes FIELD-ID ::= {
     *       { Prime-p IDENTIFIED BY prime-field } |
     *       { Characteristic-two IDENTIFIED BY characteristic-two-field }
     * }
     * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 )
        return( ret );

    if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
        memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
    {
        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
    }

    p += len;

    /* Prime-p ::= INTEGER -- Field of size p. */
    if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    grp->pbits = mbedtls_mpi_bitlen( &grp->P );

    if( p != end_field )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );

    /*
     * Curve ::= SEQUENCE {
     *       a FieldElement,
     *       b FieldElement,
     *       seed BIT STRING OPTIONAL
     *       -- Shall be present if used in SpecifiedECDomain
     *       -- with version equal to ecdpVer2 or ecdpVer3
     * }
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
        return( ret );

    end_curve = p + len;

    /*
     * FieldElement ::= OCTET STRING
     * containing an integer in the case of a prime field
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
        ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
    {
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    p += len;

    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
        ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
    {
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    p += len;

    /* Ignore seed BIT STRING OPTIONAL */
    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 )
        p += len;

    if( p != end_curve )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );

    /*
     * ECPoint ::= OCTET STRING
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
                                      ( const unsigned char *) p, len ) ) != 0 )
    {
        /*
         * If we can't read the point because it's compressed, cheat by
         * reading only the X coordinate and the parity bit of Y.
         */
        if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ||
            ( p[0] != 0x02 && p[0] != 0x03 ) ||
            len != mbedtls_mpi_size( &grp->P ) + 1 ||
            mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
            mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
            mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 )
        {
            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
        }
    }

    p += len;

    /*
     * order INTEGER
     */
    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    grp->nbits = mbedtls_mpi_bitlen( &grp->N );

    /*
     * Allow optional elements by purposefully not enforcing p == end here.
     */

    return( 0 );
}
Exemple #22
0
/*
 * Parse a SEC1 encoded private EC key
 */
static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
                                  const unsigned char *key,
                                  size_t keylen )
{
    int ret;
    int version, pubkey_done;
    size_t len;
    mbedtls_asn1_buf params;
    unsigned char *p = (unsigned char *) key;
    unsigned char *end = p + keylen;
    unsigned char *end2;

    /*
     * RFC 5915, or SEC1 Appendix C.4
     *
     * ECPrivateKey ::= SEQUENCE {
     *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
     *      privateKey     OCTET STRING,
     *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
     *      publicKey  [1] BIT STRING OPTIONAL
     *    }
     */
    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
    {
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    end = p + len;

    if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( version != 1 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );

    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
    {
        mbedtls_ecp_keypair_free( eck );
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    p += len;

    pubkey_done = 0;
    if( p != end )
    {
        /*
         * Is 'parameters' present?
         */
        if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
                        MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
        {
            if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
                ( ret = pk_use_ecparams( &params, &eck->grp )  ) != 0 )
            {
                mbedtls_ecp_keypair_free( eck );
                return( ret );
            }
        }
        else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
        {
            mbedtls_ecp_keypair_free( eck );
            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
        }

        /*
         * Is 'publickey' present? If not, or if we can't read it (eg because it
         * is compressed), create it from the private key.
         */
        if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
                        MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
        {
            end2 = p + len;

            if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
                return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );

            if( p + len != end2 )
                return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
                        MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );

            if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
                pubkey_done = 1;
            else
            {
                /*
                 * The only acceptable failure mode of pk_get_ecpubkey() above
                 * is if the point format is not recognized.
                 */
                if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
                    return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
            }
        }
        else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
        {
            mbedtls_ecp_keypair_free( eck );
            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
        }
    }

    if( ! pubkey_done &&
        ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
                                                      NULL, NULL ) ) != 0 )
    {
        mbedtls_ecp_keypair_free( eck );
        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
    {
        mbedtls_ecp_keypair_free( eck );
        return( ret );
    }

    return( 0 );
}
Exemple #23
0
int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
    int ret = 0;
    CRYSError_t CrysRet = CRYS_OK;
    void* pHeap = NULL;
    size_t heapSize = 0;
    uint8_t* pSignature = NULL;
    CRYS_ECPKI_HASH_OpMode_t hash_mode = message_size_to_hash_mode( blen );
    uint32_t signature_size =  ( ( grp->nbits + 7 ) / 8 ) *2;
    const uint32_t signature_size_for_heap = signature_size;
    mbedtls_rand_func_container cc_rand = { f_rng, p_rng };
    const CRYS_ECPKI_Domain_t*  pDomain =  CRYS_ECPKI_GetEcDomain ( convert_mbedtls_grp_id_to_crys_domain_id( grp->id ) );

#if SIZE_MAX > UINT_MAX
    if( blen > 0xFFFFFFFF )
    {
        return ( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
    }
#endif

    if ( pDomain != NULL )
    {
        uint8_t temp_buf[ MAX_KEY_SIZE_IN_BYTES ] = {0};
        cc_ecc_ws_sign_params_t* signParams = mbedtls_calloc( 1, sizeof(cc_ecc_ws_sign_params_t) );
        if ( signParams == NULL)
            return ( MBEDTLS_ERR_ECP_ALLOC_FAILED );
        pHeap = signParams;
        heapSize = sizeof(cc_ecc_ws_sign_params_t);

        pSignature = mbedtls_calloc( 1, signature_size_for_heap );
        if ( pSignature == NULL)
        {
            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
            goto cleanup;
        }

        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, temp_buf, mbedtls_mpi_size( d ) ) );

        CrysRet = CRYS_ECPKI_BuildPrivKey( pDomain,
                                       temp_buf,
                                       mbedtls_mpi_size( d ),
                                       &signParams->privKey);
        if( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
            goto cleanup;
        }

        CrysRet =  CRYS_ECDSA_Sign( &cc_rand,
                                convert_mbedtls_to_cc_rand,
                                &signParams->signContext,
                                &signParams->privKey,
                                hash_mode,
                                (uint8_t*)buf,
                                blen,
                                pSignature,
                                &signature_size );
        mbedtls_zeroize( temp_buf, sizeof(temp_buf) );
        if( CrysRet != CRYS_OK )
        {
            ret = convert_CrysError_to_mbedtls_err( CrysRet );
            goto cleanup;
        }
    }
    else
    {
        ret =  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
        goto cleanup;
    }

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( r, pSignature, ( ( grp->nbits + 7 ) / 8 ) ) );

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( s, pSignature + ( ( grp->nbits + 7 ) / 8 ), ( ( grp->nbits + 7 ) / 8 ) ) );


cleanup:

    if ( pHeap )
    {
        mbedtls_zeroize( pHeap, heapSize );
        mbedtls_free( pHeap );
    }

    if( pSignature )
    {
        mbedtls_zeroize( pSignature, signature_size_for_heap );
        mbedtls_free( pSignature );

    }

    return ( ret ) ;
}