std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh_agree( const std::string& curve_name, const std::vector<uint8_t>& peer_public_value, const Policy& policy, RandomNumberGenerator& rng, bool compressed) { secure_vector<uint8_t> ecdh_secret; std::vector<uint8_t> our_public_value; if(curve_name == "x25519") { #if defined(BOTAN_HAS_CURVE_25519) if(peer_public_value.size() != 32) { throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid X25519 key size"); } Curve25519_PublicKey peer_key(peer_public_value); policy.check_peer_key_acceptable(peer_key); Curve25519_PrivateKey priv_key(rng); PK_Key_Agreement ka(priv_key, rng, "Raw"); ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of(); // X25519 is always compressed but sent as "uncompressed" in TLS our_public_value = priv_key.public_value(); #else throw Internal_Error("Negotiated X25519 somehow, but it is disabled"); #endif } else { EC_Group group(OIDS::lookup(curve_name)); ECDH_PublicKey peer_key(group, group.OS2ECP(peer_public_value)); policy.check_peer_key_acceptable(peer_key); ECDH_PrivateKey priv_key(rng, group); PK_Key_Agreement ka(priv_key, rng, "Raw"); ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of(); our_public_value = priv_key.public_value(compressed ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED); } return std::make_pair(ecdh_secret, our_public_value); }
bool BotanDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey) { // Check parameters if ((ppSymmetricKey == NULL) || (publicKey == NULL) || (privateKey == NULL)) { return false; } // Get keys Botan::DH_PublicKey* pub = ((BotanDHPublicKey*) publicKey)->getBotanKey(); Botan::DH_PrivateKey* priv = ((BotanDHPrivateKey*) privateKey)->getBotanKey(); if (pub == NULL || priv == NULL) { ERROR_MSG("Failed to get Botan DH keys"); return false; } // Derive the secret Botan::SymmetricKey sk; try { Botan::PK_Key_Agreement ka(*priv, "Raw"); sk = ka.derive_key(0, pub->public_value()); } catch (...) { ERROR_MSG("Botan DH key agreement failed"); return false; } ByteString secret; secret.resize(sk.length()); memcpy(&secret[0], sk.begin(), sk.length()); *ppSymmetricKey = new SymmetricKey(sk.length() * 8); if (*ppSymmetricKey == NULL) { ERROR_MSG("Can't create DH secret"); return false; } if (!(*ppSymmetricKey)->setKeyBits(secret)) { delete *ppSymmetricKey; *ppSymmetricKey = NULL; return false; } return true; }
void SAFER::Base::UncheckedSetKey(const byte *userkey_1, unsigned int length, const NameValuePairs ¶ms) { bool strengthened = Strengthened(); unsigned int nof_rounds = params.GetIntValueWithDefault(Name::Rounds(), length == 8 ? (strengthened ? 8 : 6) : 10); const byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); unsigned int i, j; byte *key = keySchedule; SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); if (MAX_ROUNDS < nof_rounds) nof_rounds = MAX_ROUNDS; *key++ = (unsigned char)nof_rounds; ka[BLOCKSIZE] = 0; kb[BLOCKSIZE] = 0; for (j = 0; j < BLOCKSIZE; j++) { ka[BLOCKSIZE] ^= ka[j] = rotlFixed(userkey_1[j], 5U); kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; } for (i = 1; i <= nof_rounds; i++) { for (j = 0; j < BLOCKSIZE + 1; j++) { ka[j] = rotlFixed(ka[j], 6U); kb[j] = rotlFixed(kb[j], 6U); } for (j = 0; j < BLOCKSIZE; j++) if (strengthened) *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; else *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; for (j = 0; j < BLOCKSIZE; j++) if (strengthened) *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; else *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; } }
SAFER::SAFER(const byte *userkey_1, const byte *userkey_2, unsigned nof_rounds, bool strengthened) : keySchedule(1 + BLOCKSIZE * (1 + 2 * nof_rounds)) { unsigned int i, j; byte *key = keySchedule; SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); if (MAX_ROUNDS < nof_rounds) nof_rounds = MAX_ROUNDS; *key++ = (unsigned char)nof_rounds; ka[BLOCKSIZE] = 0; kb[BLOCKSIZE] = 0; for (j = 0; j < BLOCKSIZE; j++) { ka[BLOCKSIZE] ^= ka[j] = rotlFixed(userkey_1[j], 5U); kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; } for (i = 1; i <= nof_rounds; i++) { for (j = 0; j < BLOCKSIZE + 1; j++) { ka[j] = rotlFixed(ka[j], 6U); kb[j] = rotlFixed(kb[j], 6U); } for (j = 0; j < BLOCKSIZE; j++) if (strengthened) *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; else *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; for (j = 0; j < BLOCKSIZE; j++) if (strengthened) *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; else *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; } }
std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_dh_agree( const std::vector<uint8_t>& modulus, const std::vector<uint8_t>& generator, const std::vector<uint8_t>& peer_public_value, const Policy& policy, RandomNumberGenerator& rng) { BigInt p = BigInt::decode(modulus); BigInt g = BigInt::decode(generator); BigInt Y = BigInt::decode(peer_public_value); /* * A basic check for key validity. As we do not know q here we * cannot check that Y is in the right subgroup. However since * our key is ephemeral there does not seem to be any * advantage to bogus keys anyway. */ if(Y <= 1 || Y >= p - 1) throw TLS_Exception(Alert::ILLEGAL_PARAMETER, "Server sent bad DH key for DHE exchange"); DL_Group group(p, g); if(!group.verify_group(rng, false)) throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, "DH group validation failed"); DH_PublicKey peer_key(group, Y); policy.check_peer_key_acceptable(peer_key); DH_PrivateKey priv_key(rng, group); PK_Key_Agreement ka(priv_key, rng, "Raw"); secure_vector<uint8_t> dh_secret = CT::strip_leading_zeros( ka.derive_key(0, peer_key.public_value()).bits_of()); return std::make_pair(dh_secret, priv_key.public_value()); }
const Matrix& DispBeamColumn2d::getInitialBasicStiff() { static Matrix kb(3,3); // Zero for integral kb.Zero(); double L = crdTransf->getInitialLength(); double oneOverL = 1.0/L; //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); //const Vector &wts = quadRule.getIntegrPointWeights(numSections); double xi[maxNumSections]; beamInt->getSectionLocations(numSections, L, xi); double wt[maxNumSections]; beamInt->getSectionWeights(numSections, L, wt); // Loop over the integration points for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); Matrix ka(workArea, order, 3); ka.Zero(); //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*xi[i]; // Get the section tangent stiffness and stress resultant const Matrix &ks = theSections[i]->getInitialTangent(); // Perform numerical integration //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); //double wti = wts(i)*oneOverL; double wti = wt[i]*oneOverL; double tmp; int j, k; for (j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: for (k = 0; k < order; k++) ka(k,0) += ks(k,j)*wti; break; case SECTION_RESPONSE_MZ: for (k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; default: break; } } for (j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for (k = 0; k < 3; k++) kb(0,k) += ka(j,k); break; case SECTION_RESPONSE_MZ: for (k = 0; k < 3; k++) { tmp = ka(j,k); kb(1,k) += (xi6-4.0)*tmp; kb(2,k) += (xi6-2.0)*tmp; } break; default: break; } } } return kb; }
const Vector & DispBeamColumn2d::getResistingForceSensitivity(int gradNumber) { double L = crdTransf->getInitialLength(); double oneOverL = 1.0/L; //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); //const Vector &wts = quadRule.getIntegrPointWeights(numSections); double xi[maxNumSections]; beamInt->getSectionLocations(numSections, L, xi); double wt[maxNumSections]; beamInt->getSectionWeights(numSections, L, wt); double dLdh = crdTransf->getdLdh(); double d1oLdh = crdTransf->getd1overLdh(); double dptsdh[maxNumSections]; beamInt->getLocationsDeriv(numSections, L, dLdh, dptsdh); double dwtsdh[maxNumSections]; beamInt->getWeightsDeriv(numSections, L, dLdh, dwtsdh); // Zero for integration static Vector dqdh(3); dqdh.Zero(); // Loop over the integration points for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*xi[i]; //double wti = wts(i); double wti = wt[i]; // Get section stress resultant gradient const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber,true); // Perform numerical integration on internal force gradient double sensi; for (int j = 0; j < order; j++) { sensi = dsdh(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: dqdh(0) += sensi; break; case SECTION_RESPONSE_MZ: dqdh(1) += (xi6-4.0)*sensi; dqdh(2) += (xi6-2.0)*sensi; break; default: break; } } const Vector &s = theSections[i]->getStressResultant(); double dxi6dh = 6.0*dptsdh[i]; double dwtLdh = wt[i]*dLdh + dwtsdh[i]*L; //dwtLdh = dwtsdh[i]; // Perform numerical integration on internal force gradient for (int j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: //dqdh(0) += d1oLdh*s(j)*wti*L; break; case SECTION_RESPONSE_MZ: //dqdh(1) += (dxi6dh*oneOverL + d1oLdh*(xi6-4.0))*s(j)*wti*L; //dqdh(2) += (dxi6dh*oneOverL + d1oLdh*(xi6-2.0))*s(j)*wti*L; //dqdh(1) += oneOverL*(xi6-4.0)*s(j)*dwtLdh; //dqdh(2) += oneOverL*(xi6-2.0)*s(j)*dwtLdh; break; default: break; } } } // Transform forces static Vector dp0dh(3); // No distributed loads P.Zero(); ////////////////////////////////////////////////////////////// if (crdTransf->isShapeSensitivity()) { // Perform numerical integration to obtain basic stiffness matrix // Some extra declarations static Matrix kbmine(3,3); kbmine.Zero(); q.Zero(); double tmp; int j, k; for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*xi[i]; //double wti = wts(i); double wti = wt[i]; const Vector &s = theSections[i]->getStressResultant(); const Matrix &ks = theSections[i]->getSectionTangent(); Matrix ka(workArea, order, 3); ka.Zero(); double si; for (j = 0; j < order; j++) { si = s(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; for (k = 0; k < order; k++) { ka(k,0) += ks(k,j)*wti; } break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; for (k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; default: break; } } for (j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for (k = 0; k < 3; k++) { kbmine(0,k) += ka(j,k); } break; case SECTION_RESPONSE_MZ: for (k = 0; k < 3; k++) { tmp = ka(j,k); kbmine(1,k) += (xi6-4.0)*tmp; kbmine(2,k) += (xi6-2.0)*tmp; } break; default: break; } } } const Vector &A_u = crdTransf->getBasicTrialDisp(); double dLdh = crdTransf->getdLdh(); double d1overLdh = -dLdh/(L*L); // a^T k_s dadh v dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh); // k dAdh u const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL); // dAdh^T q P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber); } // A^T (dqdh + k dAdh u) P += crdTransf->getGlobalResistingForce(dqdh, dp0dh); return P; }
const Matrix& DispBeamColumn3d::getTangentStiff() { static Matrix kb(6,6); // Zero for integral kb.Zero(); q.Zero(); double L = crdTransf->getInitialLength(); double oneOverL = 1.0/L; //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); //const Vector &wts = quadRule.getIntegrPointWeights(numSections); double xi[maxNumSections]; beamInt->getSectionLocations(numSections, L, xi); double wt[maxNumSections]; beamInt->getSectionWeights(numSections, L, wt); // Loop over the integration points for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); Matrix ka(workArea, order, 6); ka.Zero(); double xi6 = 6.0*xi[i]; // Get the section tangent stiffness and stress resultant const Matrix &ks = theSections[i]->getSectionTangent(); const Vector &s = theSections[i]->getStressResultant(); // Perform numerical integration //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); double wti = wt[i]*oneOverL; double tmp; int j, k; for (j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: for (k = 0; k < order; k++) ka(k,0) += ks(k,j)*wti; break; case SECTION_RESPONSE_MZ: for (k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; case SECTION_RESPONSE_MY: for (k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,3) += (xi6-4.0)*tmp; ka(k,4) += (xi6-2.0)*tmp; } break; case SECTION_RESPONSE_T: for (k = 0; k < order; k++) ka(k,5) += ks(k,j)*wti; break; default: break; } } for (j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for (k = 0; k < 6; k++) kb(0,k) += ka(j,k); break; case SECTION_RESPONSE_MZ: for (k = 0; k < 6; k++) { tmp = ka(j,k); kb(1,k) += (xi6-4.0)*tmp; kb(2,k) += (xi6-2.0)*tmp; } break; case SECTION_RESPONSE_MY: for (k = 0; k < 6; k++) { tmp = ka(j,k); kb(3,k) += (xi6-4.0)*tmp; kb(4,k) += (xi6-2.0)*tmp; } break; case SECTION_RESPONSE_T: for (k = 0; k < 6; k++) kb(5,k) += ka(j,k); break; default: break; } } //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); double si; for (j = 0; j < order; j++) { si = s(j)*wt[i]; switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break; case SECTION_RESPONSE_MY: q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si; break; case SECTION_RESPONSE_T: q(5) += si; break; default: break; } } } q(0) += q0[0]; q(1) += q0[1]; q(2) += q0[2]; q(3) += q0[3]; q(4) += q0[4]; // Transform to global stiffness K = crdTransf->getGlobalStiffMatrix(kb, q); return K; }
const XC::Vector &XC::DispBeamColumn2d::getResistingForceSensitivity(int gradNumber) { const size_t numSections= getNumSections(); const Matrix &pts = quadRule.getIntegrPointCoords(numSections); const Vector &wts = quadRule.getIntegrPointWeights(numSections); double L = theCoordTransf->getInitialLength(); double oneOverL = 1.0/L; // Zero for integration q.Zero(); static XC::Vector qsens(3); qsens.Zero(); // Some extra declarations static XC::Matrix kbmine(3,3); kbmine.Zero(); int j, k; double d1oLdh = 0.0; // Check if a nodal coordinate is random bool randomNodeCoordinate = false; static XC::ID nodeParameterID(2); nodeParameterID(0) = theNodes[0]->getCrdsSensitivity(); nodeParameterID(1) = theNodes[1]->getCrdsSensitivity(); if(nodeParameterID(0) != 0 || nodeParameterID(1) != 0) { randomNodeCoordinate = true; const XC::Vector &ndICoords = theNodes[0]->getCrds(); const XC::Vector &ndJCoords = theNodes[1]->getCrds(); double dx = ndJCoords(0) - ndICoords(0); double dy = ndJCoords(1) - ndICoords(1); if(nodeParameterID(0) == 1) // here x1 is random d1oLdh = dx/(L*L*L); if(nodeParameterID(0) == 2) // here y1 is random d1oLdh = dy/(L*L*L); if(nodeParameterID(1) == 1) // here x2 is random d1oLdh = -dx/(L*L*L); if(nodeParameterID(1) == 2) // here y2 is random d1oLdh = -dy/(L*L*L); } // Loop over the integration points for(size_t i= 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const XC::ID &code = theSections[i]->getType(); double xi6 = 6.0*pts(i,0); double wti = wts(i); // Get section stress resultant gradient const XC::Vector &s = theSections[i]->getStressResultant(); const XC::Vector &sens = theSections[i]->getStressResultantSensitivity(gradNumber,true); // Perform numerical integration on internal force gradient //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); double si; double sensi; for(j = 0; j < order; j++) { si = s(j)*wti; sensi = sens(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; qsens(0) += sensi; break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; qsens(1) += (xi6-4.0)*sensi; qsens(2) += (xi6-2.0)*sensi; break; default: break; } } if(randomNodeCoordinate) { // Perform numerical integration to obtain basic stiffness matrix //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); double tmp; const XC::Matrix &ks = theSections[i]->getSectionTangent(); Matrix ka(workArea, order, 3); ka.Zero(); for(j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < order; k++) { ka(k,0) += ks(k,j)*wti; } break; case SECTION_RESPONSE_MZ: for(k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; default: break; } } for(j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < 3; k++) { kbmine(0,k) += ka(j,k); } break; case SECTION_RESPONSE_MZ: for(k = 0; k < 3; k++) { tmp = ka(j,k); kbmine(1,k) += (xi6-4.0)*tmp; kbmine(2,k) += (xi6-2.0)*tmp; } break; default: break; } } } } static XC::Vector dqdh(3); const XC::Vector &dAdh_u = theCoordTransf->getBasicTrialDispShapeSensitivity(); //dqdh = (1.0/L) * (kbmine * dAdh_u); dqdh.addMatrixVector(0.0, kbmine, dAdh_u, oneOverL); static XC::Vector dkbdh_v(3); const XC::Vector &A_u = theCoordTransf->getBasicTrialDisp(); //dkbdh_v = (d1oLdh) * (kbmine * A_u); dkbdh_v.addMatrixVector(0.0, kbmine, A_u, d1oLdh); // Transform forces static XC::Vector dummy(3); // No distributed loads // Term 5 P = theCoordTransf->getGlobalResistingForce(qsens,dummy); if(randomNodeCoordinate) { // Term 1 P += theCoordTransf->getGlobalResistingForceShapeSensitivity(q,dummy); // Term 2 P += theCoordTransf->getGlobalResistingForce(dqdh,dummy); // Term 4 P += theCoordTransf->getGlobalResistingForce(dkbdh_v,dummy); } return P; }
const XC::Matrix &XC::DispBeamColumn2d::getTangentStiff(void) const { static Matrix kb(3,3); this->getBasicStiff(kb); // Zero for integral q.Zero(); const size_t numSections= getNumSections(); const Matrix &pts = quadRule.getIntegrPointCoords(numSections); const Vector &wts = quadRule.getIntegrPointWeights(numSections); const double L = theCoordTransf->getInitialLength(); const double oneOverL = 1.0/L; // Loop over the integration points for(size_t i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const XC::ID &code = theSections[i]->getType(); Matrix ka(workArea, order, 3); ka.Zero(); double xi6 = 6.0*pts(i,0); // Get the section tangent stiffness and stress resultant const XC::Matrix &ks = theSections[i]->getSectionTangent(); const XC::Vector &s = theSections[i]->getStressResultant(); // Perform numerical integration //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); double wti = wts(i)*oneOverL; double tmp; int j, k; for(j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < order; k++) ka(k,0) += ks(k,j)*wti; break; case SECTION_RESPONSE_MZ: for(k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; default: break; } } for(j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < 3; k++) kb(0,k) += ka(j,k); break; case SECTION_RESPONSE_MZ: for(k = 0; k < 3; k++) { tmp = ka(j,k); kb(1,k) += (xi6-4.0)*tmp; kb(2,k) += (xi6-2.0)*tmp; } break; default: break; } } //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); double si; for(j = 0; j < order; j++) { si = s(j)*wts(i); switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break; default: break; } } } // Add effects of element loads, q = q(v) + q0 q(0) += q0[0]; q(1) += q0[1]; q(2) += q0[2]; // Transform to global stiffness K = theCoordTransf->getGlobalStiffMatrix(kb, q); if(isDead()) K*=dead_srf; return K; }
bool BotanDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey) { // Check parameters if ((ppSymmetricKey == NULL) || (publicKey == NULL) || (privateKey == NULL)) { return false; } // Get keys Botan::DH_PublicKey* pub = ((BotanDHPublicKey*) publicKey)->getBotanKey(); BotanDH_PrivateKey* priv = ((BotanDHPrivateKey*) privateKey)->getBotanKey(); if (pub == NULL || priv == NULL || priv->impl == NULL) { ERROR_MSG("Failed to get Botan DH keys"); return false; } // Derive the secret Botan::SymmetricKey sk; try { #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33) BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); Botan::PK_Key_Agreement ka(*priv->impl, *rng->getRNG(), "Raw"); #else Botan::PK_Key_Agreement ka(*priv->impl, "Raw"); #endif sk = ka.derive_key(0, pub->public_value()); } catch (std::exception& e) { ERROR_MSG("Botan DH key agreement failed: %s", e.what()); return false; } ByteString secret; // We compensate that Botan removes leading zeros int size = ((BotanDHPublicKey*) publicKey)->getOutputLength(); int keySize = sk.length(); secret.wipe(size); memcpy(&secret[0] + size - keySize, sk.begin(), keySize); *ppSymmetricKey = new SymmetricKey(secret.size() * 8); if (*ppSymmetricKey == NULL) { ERROR_MSG("Can't create DH secret"); return false; } if (!(*ppSymmetricKey)->setKeyBits(secret)) { delete *ppSymmetricKey; *ppSymmetricKey = NULL; return false; } return true; }
// Apply the phong model to this point on the surface of the object, returning // the color of that point. Vec3d Material::shade( Scene *scene, const ray& r, const isect& i ) const { // YOUR CODE HERE // For now, this method just returns the diffuse color of the object. // This gives a single matte color for every distinct surface in the // scene, and that's it. Simple, but enough to get you started. // (It's also inconsistent with the phong model...) // Your mission is to fill in this method with the rest of the phong // shading model, including the contributions of all the light sources. // You will need to call both distanceAttenuation() and shadowAttenuation() // somewhere in your code in order to compute shadows and light falloff. if( debugMode ) std::cout << "Debugging Phong code..." << std::endl; //Intersection Point Vec3d P = r.at(i.t); Vec3d L = Vec3d(0,0,0); Vec3d V = -r.getDirection(); //======[ Emission ]====== L += ke(i); if(debugMode) std::cout << "ke(i): " << ke(i) <<"\n"; //======[ Ambient ]====== //missing Ka L += prod(ka(i),scene->ambient()); if(debugMode){ std::cout << "ambient: " << scene->ambient() <<"\n"; std::cout << "ka(i): " << ka(i) <<"\n"; } //iterate through lights for ( std::vector<Light*>::const_iterator litr = scene->beginLights(); litr != scene->endLights(); ++litr ) { Vec3d Lc; //light contribution Light* pLight = *litr; Vec3d sa = pLight->shadowAttenuation(P); double da = pLight->distanceAttenuation(P); //======[ Diffuse ]====== Vec3d direction = pLight->getDirection(P); Vec3d normal = i.N; if(debugMode) { std::cout << "D: "; clamp((normal*direction)*kd(i)).print(); } Lc = clamp((normal*direction)*kd(i)); //======[ Specular ]====== Vec3d H = (V+direction)/2.0; if(debugMode) { std::cout << "S: "; clamp(ks(i)*pow((normal*H),shininess(i))).print(); std::cout <<"sa: "; sa.print(); } Lc += clamp(ks(i)*pow((normal*H),shininess(i))); Lc = da * prod(Lc,sa); L+=Lc; } if(debugMode){ std::cout <<"L: "; L.print(); } return L; }
/* * Create a new Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, Handshake_State& state, const Policy& policy, Credentials_Manager& creds, const Public_Key* server_public_key, const std::string& hostname, RandomNumberGenerator& rng) { const std::string kex_algo = state.ciphersuite().kex_algo(); if(kex_algo == "PSK") { std::string identity_hint = ""; if(state.server_kex()) { TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params()); identity_hint = reader.get_string(2, 0, 65535); } const std::string psk_identity = creds.psk_identity("tls-client", hostname, identity_hint); append_tls_length_value(m_key_material, psk_identity, 2); SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity); std::vector<byte> zeros(psk.length()); append_tls_length_value(m_pre_master, zeros, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } else if(state.server_kex()) { TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params()); SymmetricKey psk; if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { std::string identity_hint = reader.get_string(2, 0, 65535); const std::string psk_identity = creds.psk_identity("tls-client", hostname, identity_hint); append_tls_length_value(m_key_material, psk_identity, 2); psk = creds.psk("tls-client", hostname, psk_identity); } if(kex_algo == "DH" || kex_algo == "DHE_PSK") { BigInt p = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); BigInt Y = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); if(reader.remaining_bytes()) throw Decoding_Error("Bad params size for DH key exchange"); if(p.bits() < policy.minimum_dh_group_size()) throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, "Server sent DH group of " + std::to_string(p.bits()) + " bits, policy requires at least " + std::to_string(policy.minimum_dh_group_size())); /* * A basic check for key validity. As we do not know q here we * cannot check that Y is in the right subgroup. However since * our key is ephemeral there does not seem to be any * advantage to bogus keys anyway. */ if(Y <= 1 || Y >= p - 1) throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, "Server sent bad DH key for DHE exchange"); DL_Group group(p, g); if(!group.verify_group(rng, false)) throw TLS_Exception(Alert::INSUFFICIENT_SECURITY, "DH group validation failed"); DH_PublicKey counterparty_key(group, Y); DH_PrivateKey priv_key(rng, group); PK_Key_Agreement ka(priv_key, "Raw"); secure_vector<byte> dh_secret = CT::strip_leading_zeros( ka.derive_key(0, counterparty_key.public_value()).bits_of()); if(kex_algo == "DH") m_pre_master = dh_secret; else { append_tls_length_value(m_pre_master, dh_secret, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } append_tls_length_value(m_key_material, priv_key.public_value(), 2); } else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") { const byte curve_type = reader.get_byte(); if(curve_type != 3) throw Decoding_Error("Server sent non-named ECC curve"); const u16bit curve_id = reader.get_u16bit(); const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id); if(name == "") throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id)); EC_Group group(name); std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255); ECDH_PublicKey counterparty_key(group, OS2ECP(ecdh_key, group.get_curve())); ECDH_PrivateKey priv_key(rng, group); PK_Key_Agreement ka(priv_key, "Raw"); secure_vector<byte> ecdh_secret = ka.derive_key(0, counterparty_key.public_value()).bits_of(); if(kex_algo == "ECDH") m_pre_master = ecdh_secret; else { append_tls_length_value(m_pre_master, ecdh_secret, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } append_tls_length_value(m_key_material, priv_key.public_value(), 1); } #if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); std::vector<byte> salt = reader.get_range<byte>(1, 1, 255); const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535)); const std::string srp_group = srp6_group_identifier(N, g); const std::string srp_identifier = creds.srp_identifier("tls-client", hostname); const std::string srp_password = creds.srp_password("tls-client", hostname, srp_identifier); std::pair<BigInt, SymmetricKey> srp_vals = srp6_client_agree(srp_identifier, srp_password, srp_group, "SHA-1", salt, B, rng); append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2); m_pre_master = srp_vals.second.bits_of(); } #endif else { throw Internal_Error("Client_Key_Exchange: Unknown kex " + kex_algo); } reader.assert_done(); } else { // No server key exchange msg better mean RSA kex + RSA key in cert if(kex_algo != "RSA") throw Unexpected_Message("No server kex but negotiated kex " + kex_algo); if(!server_public_key) throw Internal_Error("No server public key for RSA exchange"); if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key)) { const Protocol_Version offered_version = state.client_hello()->version(); m_pre_master = rng.random_vec(48); m_pre_master[0] = offered_version.major_version(); m_pre_master[1] = offered_version.minor_version(); PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15"); const std::vector<byte> encrypted_key = encryptor.encrypt(m_pre_master, rng); append_tls_length_value(m_key_material, encrypted_key, 2); } else throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Expected a RSA key in server cert but got " + server_public_key->algo_name()); } state.hash().update(io.send(*this)); }
/* * Read a Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents, const Handshake_State& state, const Private_Key* server_rsa_kex_key, Credentials_Manager& creds, const Policy& policy, RandomNumberGenerator& rng) { const std::string kex_algo = state.ciphersuite().kex_algo(); if(kex_algo == "RSA") { BOTAN_ASSERT(state.server_certs() && !state.server_certs()->cert_chain().empty(), "RSA key exchange negotiated so server sent a certificate"); if(!server_rsa_kex_key) throw Internal_Error("Expected RSA kex but no server kex key set"); if(!dynamic_cast<const RSA_PrivateKey*>(server_rsa_kex_key)) throw Internal_Error("Expected RSA key but got " + server_rsa_kex_key->algo_name()); PK_Decryptor_EME decryptor(*server_rsa_kex_key, "PKCS1v15"); Protocol_Version client_version = state.client_hello()->version(); /* * This is used as the pre-master if RSA decryption fails. * Otherwise we can be used as an oracle. See Bleichenbacher * "Chosen Ciphertext Attacks against Protocols Based on RSA * Encryption Standard PKCS #1", Crypto 98 * * Create it here instead if in the catch clause as otherwise we * expose a timing channel WRT the generation of the fake value. * Some timing channel likely remains due to exception handling * and the like. */ secure_vector<byte> fake_pre_master = rng.random_vec(48); fake_pre_master[0] = client_version.major_version(); fake_pre_master[1] = client_version.minor_version(); try { TLS_Data_Reader reader("ClientKeyExchange", contents); m_pre_master = decryptor.decrypt(reader.get_range<byte>(2, 0, 65535)); if(m_pre_master.size() != 48 || client_version.major_version() != m_pre_master[0] || client_version.minor_version() != m_pre_master[1]) { throw Decoding_Error("Client_Key_Exchange: Secret corrupted"); } } catch(...) { m_pre_master = fake_pre_master; } } else { TLS_Data_Reader reader("ClientKeyExchange", contents); SymmetricKey psk; if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { const std::string psk_identity = reader.get_string(2, 0, 65535); psk = creds.psk("tls-server", state.client_hello()->sni_hostname(), psk_identity); if(psk.length() == 0) { if(policy.hide_unknown_users()) psk = SymmetricKey(rng, 16); else throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, "No PSK for identifier " + psk_identity); } } if(kex_algo == "PSK") { std::vector<byte> zeros(psk.length()); append_tls_length_value(m_pre_master, zeros, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } #if defined(BOTAN_HAS_SRP6) else if(kex_algo == "SRP_SHA") { SRP6_Server_Session& srp = state.server_kex()->server_srp_params(); m_pre_master = srp.step2(BigInt::decode(reader.get_range<byte>(2, 0, 65535))).bits_of(); } #endif else if(kex_algo == "DH" || kex_algo == "DHE_PSK" || kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") { const Private_Key& private_key = state.server_kex()->server_kex_key(); const PK_Key_Agreement_Key* ka_key = dynamic_cast<const PK_Key_Agreement_Key*>(&private_key); if(!ka_key) throw Internal_Error("Expected key agreement key type but got " + private_key.algo_name()); try { PK_Key_Agreement ka(*ka_key, "Raw"); std::vector<byte> client_pubkey; if(ka_key->algo_name() == "DH") client_pubkey = reader.get_range<byte>(2, 0, 65535); else client_pubkey = reader.get_range<byte>(1, 0, 255); secure_vector<byte> shared_secret = ka.derive_key(0, client_pubkey).bits_of(); if(ka_key->algo_name() == "DH") shared_secret = CT::strip_leading_zeros(shared_secret); if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") { append_tls_length_value(m_pre_master, shared_secret, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } else m_pre_master = shared_secret; } catch(std::exception &) { /* * Something failed in the DH computation. To avoid possible * timing attacks, randomize the pre-master output and carry * on, allowing the protocol to fail later in the finished * checks. */ m_pre_master = rng.random_vec(ka_key->public_value().size()); } } else throw Internal_Error("Client_Key_Exchange: Unknown kex type " + kex_algo); } }