/*! * \copyright Copyright (c) 2014 Governikus GmbH & Co. KG */ #include #include "pace/ec/EcdhGenericMapping.h" #include "pace/ec/EcUtil.h" #include using namespace governikus; Q_DECLARE_LOGGING_CATEGORY(card) EcdhGenericMapping::EcdhGenericMapping(const QSharedPointer& pCurve) : DomainParameterMapping() , mCurve(pCurve) , mTerminalKey() { } EcdhGenericMapping::~EcdhGenericMapping() { } QByteArray EcdhGenericMapping::generateTerminalMappingData() { Q_ASSERT(!mCurve.isNull()); mTerminalKey = EcUtil::create(EC_KEY_new()); if (!EC_KEY_set_group(mTerminalKey.data(), mCurve.data())) { qCCritical(card) << "Error EC_KEY_set_group"; } if (!EC_KEY_generate_key(mTerminalKey.data())) { qCCritical(card) << "Error EC_KEY_generate_key"; } return EcUtil::point2oct(mCurve, EC_KEY_get0_public_key(mTerminalKey.data())); } QSharedPointer EcdhGenericMapping::generateEphemeralDomainParameters(const QByteArray& pCardMappingData, const QByteArray& pNonce) { QSharedPointer cardPubKey = EcUtil::oct2point(mCurve, pCardMappingData); if (cardPubKey == nullptr) { return QSharedPointer(); } if (!EC_POINT_cmp(mCurve.data(), EC_KEY_get0_public_key(mTerminalKey.data()), cardPubKey.data(), nullptr)) { qCCritical(card) << "The exchanged public keys are equal."; return QSharedPointer(); } QSharedPointer s = EcUtil::create(BN_new()); if (!BN_bin2bn(reinterpret_cast(pNonce.constData()), pNonce.size(), s.data())) { qCCritical(card) << "Cannot convert nonce to BIGNUM"; return QSharedPointer(); } QSharedPointer newGenerator = createNewGenerator(cardPubKey, s); setGenerator(newGenerator); return mCurve; } QSharedPointer EcdhGenericMapping::createNewGenerator(const QSharedPointer& pCardPubKey, const QSharedPointer& pS) { QSharedPointer H = EcUtil::create(EC_POINT_new(mCurve.data())); if (!EC_POINT_mul(mCurve.data(), H.data(), nullptr, pCardPubKey.data(), EC_KEY_get0_private_key(mTerminalKey.data()), nullptr)) { qCCritical(card) << "Calculation of elliptic curve point H failed"; return QSharedPointer(); } QSharedPointer G_tilde = EcUtil::create(EC_POINT_new(mCurve.data())); if (!EC_POINT_mul(mCurve.data(), G_tilde.data(), pS.data(), H.data(), BN_value_one(), nullptr)) { qCCritical(card) << "Calculation of elliptic curve point G_tilde failed"; return QSharedPointer(); } return G_tilde; } void EcdhGenericMapping::setGenerator(const QSharedPointer& pNewGenerator) { QSharedPointer curveOrder = EcUtil::create(BN_new()); if (!EC_GROUP_get_order(mCurve.data(), curveOrder.data(), nullptr)) { qCCritical(card) << "Calculation of curveOrder failed"; return; } QSharedPointer curveCofactor = EcUtil::create(BN_new()); if (!EC_GROUP_get_cofactor(mCurve.data(), curveCofactor.data(), nullptr)) { qCCritical(card) << "Calculation of curveCofactor failed"; return; } // Da Die Kurve Primordnung hat, entspricht die Ordnung des neuen Erzeugers der, des alten Erzeugers if (!EC_GROUP_set_generator(mCurve.data(), pNewGenerator.data(), curveOrder.data(), curveCofactor.data())) { qCCritical(card) << "Error EC_GROUP_set_generator"; return; } if (!EC_GROUP_check(mCurve.data(), nullptr)) { qCCritical(card) << "Error EC_GROUP_check"; return; } }