void fuzz(const uint8_t in[], size_t len) { if(len % 2 == 1 || len > 2*4096/8) return; const size_t part_len = len / 2; const Botan::BigInt x = Botan::BigInt::decode(in, part_len); Botan::BigInt mod = Botan::BigInt::decode(in + part_len, part_len); mod.set_bit(0); if(mod < 3 || x >= mod) return; const Botan::BigInt ref = Botan::inverse_euclid(x, mod); const Botan::BigInt ct = Botan::ct_inverse_mod_odd_modulus(x, mod); //Botan::BigInt mon = Botan::normalized_montgomery_inverse(x, mod); if(ref != ct) { FUZZER_WRITE_AND_CRASH("X = " << x << "\n" << "P = " << mod << "\n" << "GCD = " << gcd(x, mod) << "\n" << "Ref = " << ref << "\n" << "CT = " << ct << "\n" << "RefCheck = " << (ref*ref)%mod << "\n" << "CTCheck = " << (ct*ct)%mod << "\n"); } }
// Key factory bool BotanDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */) { // Check parameters if ((ppKeyPair == NULL) || (parameters == NULL)) { return false; } if (!parameters->areOfType(DHParameters::type)) { ERROR_MSG("Invalid parameters supplied for DH key generation"); return false; } DHParameters* params = (DHParameters*) parameters; // Generate the key-pair BotanDH_PrivateKey* dh = NULL; try { BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); // PKCS#3: 2^(l-1) <= x < 2^l Botan::BigInt x; if (params->getXBitLength() > 0) { x.randomize(*rng->getRNG(), params->getXBitLength()); } dh = new BotanDH_PrivateKey(*rng->getRNG(), Botan::DL_Group(BotanUtil::byteString2bigInt(params->getP()), BotanUtil::byteString2bigInt(params->getG())), x); } catch (std::exception& e) { ERROR_MSG("DH key generation failed with %s", e.what()); return false; } // Create an asymmetric key-pair object to return BotanDHKeyPair* kp = new BotanDHKeyPair(); ((BotanDHPublicKey*) kp->getPublicKey())->setFromBotan(dh); ((BotanDHPrivateKey*) kp->getPrivateKey())->setFromBotan(dh); *ppKeyPair = kp; // Release the key delete dh; return true; }
CK_OBJECT_HANDLE SoftDatabase::importPublicKey(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { // Begin the transaction if(sqlite3_exec(db, "BEGIN IMMEDIATE;", NULL, NULL, NULL) != SQLITE_OK) { return CK_INVALID_HANDLE; } CHECK_DB_RESPONSE(sqlite3_step(insert_object_sql) != SQLITE_DONE); CK_OBJECT_HANDLE objectID = sqlite3_last_insert_rowid(db); sqlite3_reset(insert_object_sql); CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE; CK_DATE emptyDate; CK_MECHANISM_TYPE mechType = CK_UNAVAILABLE_INFORMATION; // Created by db handle and application. So we can remove the correct session objects in the future. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED, &db, sizeof(db)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED+1, appID, strlen(appID)) != CKR_OK); // General information CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LOCAL, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_KEY_GEN_MECHANISM, &mechType, sizeof(mechType)) != CKR_OK); // Default values, may be changed by the template. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LABEL, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ID, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_SUBJECT, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_PRIVATE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODIFIABLE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TOKEN, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_DERIVE, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ENCRYPT, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY_RECOVER, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_WRAP, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TRUSTED, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_START_DATE, &emptyDate, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_END_DATE, &emptyDate, 0) != CKR_OK); // Extract the attributes for(CK_ULONG i = 0; i < ulCount; i++) { if(pTemplate[i].type == CKA_MODULUS) { Botan::BigInt bigModulus = Botan::BigInt(0); bigModulus.binary_decode((Botan::byte*)pTemplate[i].pValue, pTemplate[i].ulValueLen); CK_ULONG bits = bigModulus.bits(); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODULUS_BITS, &bits, sizeof(bits)) != CKR_OK); } CHECK_DB_RESPONSE(this->saveAttribute(objectID, pTemplate[i].type, pTemplate[i].pValue, pTemplate[i].ulValueLen) != CKR_OK); } sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); return objectID; }
bool ne7ssh_crypt::makeKexSecret (Botan::SecureVector<Botan::byte> &result, Botan::BigInt &f) { PK_Key_Agreement key_agreement(*privKexKey, "Raw"); SymmetricKey negotiated = key_agreement.derive_key(32, (byte*)f.data(), f.bytes(), ""); // SymmetricKey negotiated = privKexKey->derive_key (f); if (!negotiated.length()) return false; BigInt Kint (negotiated.begin(), negotiated.length()); ne7ssh_string::bn2vector(result, Kint); K = Botan::SecureVector<Botan::byte>(result); delete privKexKey; privKexKey = 0; return true; }
// Remove (and return) any small (< 2^16) factors std::vector<Botan::BigInt> remove_small_factors(Botan::BigInt& n) { std::vector<Botan::BigInt> factors; while(n.is_even()) { factors.push_back(2); n /= 2; } for(size_t j = 0; j != Botan::PRIME_TABLE_SIZE; j++) { uint16_t prime = Botan::PRIMES[j]; if(n < prime) { break; } Botan::BigInt x = Botan::gcd(n, prime); if(x != 1) { n /= x; while(x != 1) { x /= prime; factors.push_back(prime); } } } return factors; }
QByteArray AbstractSshPacket::encodeMpInt(const Botan::BigInt &number) { if (number.is_zero()) return QByteArray(4, 0); int stringLength = number.bytes(); const bool positiveAndMsbSet = number.sign() == Botan::BigInt::Positive && (number.byte_at(stringLength - 1) & 0x80); if (positiveAndMsbSet) ++stringLength; QByteArray data; data.resize(4 + stringLength); int pos = 4; if (positiveAndMsbSet) data[pos++] = '\0'; number.binary_encode(reinterpret_cast<Botan::byte *>(data.data()) + pos); setLengthField(data); return data; }
bool ne7ssh_crypt::getDHGroup14Sha1Public (Botan::BigInt &publicKey) { #if BOTAN_PRE_15 privKexKey = new DH_PrivateKey (get_dl_group("IETF-2048")); #elif BOTAN_PRE_18 privKexKey = new DH_PrivateKey (DL_Group("modp/ietf/2048")); #else privKexKey = new DH_PrivateKey (*ne7ssh::rng, DL_Group("modp/ietf/2048")); #endif DH_PublicKey pubKexKey = *privKexKey; publicKey = pubKexKey.get_y(); if (publicKey.is_zero()) return false; else return true; }
ticks ECDSA_Timing_Test::measure_critical_function(std::vector<uint8_t> input) { const Botan::BigInt k(input.data(), input.size()); const Botan::BigInt msg(Timing_Test::timing_test_rng(), m_order.bits()); ticks start = get_ticks(); //The following ECDSA operations involve and should not leak any information about k. const Botan::PointGFp k_times_P = m_base_point.blinded_multiply(k, Timing_Test::timing_test_rng()); const Botan::BigInt r = m_mod_order.reduce(k_times_P.get_affine_x()); const Botan::BigInt s = m_mod_order.multiply(inverse_mod(k, m_order), mul_add(m_x, r, msg)); ticks end = get_ticks(); return (end - start); }
bool ne7ssh_string::getBigInt(Botan::BigInt& result) { SecureVector<Botan::byte> tmpVar(_buffer); uint32 len; len = ntohl(*((uint32*)tmpVar.begin())); if (len > tmpVar.size()) { return false; } BigInt tmpBI(tmpVar.begin() + sizeof(uint32), len); result.swap(tmpBI); _buffer = SecureVector<Botan::byte>(tmpVar.begin() + sizeof(uint32) + len, tmpVar.size() - sizeof(uint32) - len); return true; }
CK_OBJECT_HANDLE SoftDatabase::addRSAKeyPub(CK_STATE state, Botan::RSA_PrivateKey *rsaKey, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount) { // Begin the transaction if(sqlite3_exec(db, "BEGIN IMMEDIATE;", NULL, NULL, NULL) != SQLITE_OK) { return CK_INVALID_HANDLE; } CHECK_DB_RESPONSE(sqlite3_step(insert_object_sql) != SQLITE_DONE); CK_OBJECT_HANDLE objectID = sqlite3_last_insert_rowid(db); sqlite3_reset(insert_object_sql); CK_OBJECT_CLASS oClass = CKO_PUBLIC_KEY; CK_KEY_TYPE keyType = CKK_RSA; CK_MECHANISM_TYPE mechType = CKM_RSA_PKCS_KEY_PAIR_GEN; CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE; CK_DATE emptyDate; // Created by db handle and application. So we can remove the correct session objects in the future. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED, &db, sizeof(db)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VENDOR_DEFINED+1, appID, strlen(appID)) != CKR_OK); // General information CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_CLASS, &oClass, sizeof(oClass)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_KEY_TYPE, &keyType, sizeof(keyType)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_KEY_GEN_MECHANISM, &mechType, sizeof(mechType)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LOCAL, &ckTrue, sizeof(ckTrue)) != CKR_OK); // Default values, may be changed by the template. CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_LABEL, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ID, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_SUBJECT, NULL_PTR, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_PRIVATE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODIFIABLE, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TOKEN, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_DERIVE, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_ENCRYPT, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_VERIFY_RECOVER, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_WRAP, &ckTrue, sizeof(ckTrue)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_TRUSTED, &ckFalse, sizeof(ckFalse)) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_START_DATE, &emptyDate, 0) != CKR_OK); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_END_DATE, &emptyDate, 0) != CKR_OK); // The RSA modulus bits Botan::IF_Scheme_PublicKey *ifKey = dynamic_cast<Botan::IF_Scheme_PublicKey*>(rsaKey); Botan::BigInt bigModulus = ifKey->get_n(); CK_ULONG bits = bigModulus.bits(); CHECK_DB_RESPONSE(this->saveAttribute(objectID, CKA_MODULUS_BITS, &bits, sizeof(bits)) != CKR_OK); // The RSA modulus CHECK_DB_RESPONSE(this->saveAttributeBigInt(objectID, CKA_MODULUS, &bigModulus) != CKR_OK); // The RSA public exponent Botan::BigInt bigExponent = ifKey->get_e(); CHECK_DB_RESPONSE(this->saveAttributeBigInt(objectID, CKA_PUBLIC_EXPONENT, &bigExponent) != CKR_OK); CK_BBOOL trusted; // Extract the attributes from the template for(CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++) { switch(pPublicKeyTemplate[i].type) { // Byte array case CKA_LABEL: case CKA_ID: case CKA_SUBJECT: CHECK_DB_RESPONSE(this->saveAttribute(objectID, pPublicKeyTemplate[i].type, pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen) != CKR_OK); break; // Bool case CKA_DERIVE: case CKA_TOKEN: case CKA_PRIVATE: case CKA_MODIFIABLE: case CKA_ENCRYPT: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_WRAP: if(pPublicKeyTemplate[i].ulValueLen == sizeof(CK_BBOOL)) { CHECK_DB_RESPONSE(this->saveAttribute(objectID, pPublicKeyTemplate[i].type, pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen) != CKR_OK); } break; case CKA_TRUSTED: // Check for the correct size CHECK_DB_RESPONSE(pPublicKeyTemplate[i].ulValueLen != sizeof(CK_BBOOL)) // CKA_TRUSTED can only be set to true by SO trusted = *(CK_BBOOL*)pPublicKeyTemplate[i].pValue; CHECK_DB_RESPONSE(state != CKS_RW_SO_FUNCTIONS && trusted != CK_FALSE) CHECK_DB_RESPONSE(this->saveAttribute(objectID, pPublicKeyTemplate[i].type, pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen) != CKR_OK); break; // Date case CKA_START_DATE: case CKA_END_DATE: if(pPublicKeyTemplate[i].ulValueLen == sizeof(CK_DATE) || pPublicKeyTemplate[i].ulValueLen == 0) { CHECK_DB_RESPONSE(this->saveAttribute(objectID, pPublicKeyTemplate[i].type, pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen) != CKR_OK); } break; default: break; } } sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); return objectID; }