uint64_t NyuziGNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); return pRegion.size(); }
/* * EMSA1 BSI Encode Operation */ SecureVector<byte> EMSA1_BSI::encoding_of(const MemoryRegion<byte>& msg, u32bit output_bits, RandomNumberGenerator&) { if(msg.size() != hash_ptr()->OUTPUT_LENGTH) throw Encoding_Error("EMSA1_BSI::encoding_of: Invalid size for input"); if(8*msg.size() <= output_bits) return msg; throw Encoding_Error("EMSA1_BSI::encoding_of: max key input size exceeded"); }
/* * Split up and process handshake messages */ void TLS_Server::read_handshake(byte rec_type, const MemoryRegion<byte>& rec_buf) { if(rec_type == HANDSHAKE) { if(!state) state = new Handshake_State; state->queue.write(&rec_buf[0], rec_buf.size()); } while(true) { Handshake_Type type = HANDSHAKE_NONE; SecureVector<byte> contents; if(rec_type == HANDSHAKE) { if(state->queue.size() >= 4) { byte head[4] = { 0 }; state->queue.peek(head, 4); const size_t length = make_u32bit(0, head[1], head[2], head[3]); if(state->queue.size() >= length + 4) { type = static_cast<Handshake_Type>(head[0]); contents.resize(length); state->queue.read(head, 4); state->queue.read(&contents[0], contents.size()); } } } else if(rec_type == CHANGE_CIPHER_SPEC) { if(state->queue.size() == 0 && rec_buf.size() == 1 && rec_buf[0] == 1) type = HANDSHAKE_CCS; else throw Decoding_Error("Malformed ChangeCipherSpec message"); } else throw Decoding_Error("Unknown message type in handshake processing"); if(type == HANDSHAKE_NONE) break; process_handshake_msg(type, contents); if(type == HANDSHAKE_CCS || !state) break; } }
/* * Generate one of the Sboxes */ void Blowfish::generate_sbox(MemoryRegion<u32bit>& box, u32bit& L, u32bit& R, const byte salt[16], size_t salt_off) const { const u32bit* S1 = &S[0]; const u32bit* S2 = &S[256]; const u32bit* S3 = &S[512]; const u32bit* S4 = &S[768]; for(size_t i = 0; i != box.size(); i += 2) { L ^= load_be<u32bit>(salt, (i + salt_off) % 4); R ^= load_be<u32bit>(salt, (i + salt_off + 1) % 4); for(size_t j = 0; j != 16; j += 2) { L ^= P[j]; R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ S3[get_byte(2, L)]) + S4[get_byte(3, L)]; R ^= P[j+1]; L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ S3[get_byte(2, R)]) + S4[get_byte(3, R)]; } u32bit T = R; R = L ^ P[16]; L = T ^ P[17]; box[i] = L; box[i+1] = R; } }
SecureVector<byte> rfc3394_keyunwrap(const MemoryRegion<byte>& key, const SymmetricKey& kek, Algorithm_Factory& af) { if(key.size() < 16 || key.size() % 8 != 0) throw std::invalid_argument("Bad input key size for NIST key unwrap"); std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af)); aes->set_key(kek); const size_t n = (key.size() - 8) / 8; SecureVector<byte> R(n * 8); SecureVector<byte> A(16); for(size_t i = 0; i != 8; ++i) A[i] = key[i]; copy_mem(&R[0], key.begin() + 8, key.size() - 8); for(size_t j = 0; j <= 5; ++j) { for(size_t i = n; i != 0; --i) { const u32bit t = (5 - j) * n + i; byte t_buf[4] = { 0 }; store_be(t, t_buf); xor_buf(&A[4], &t_buf[0], 4); copy_mem(&A[8], &R[8*(i-1)], 8); aes->decrypt(&A[0]); copy_mem(&R[8*(i-1)], &A[8], 8); } } if(load_be<u64bit>(&A[0], 0) != 0xA6A6A6A6A6A6A6A6) throw Integrity_Failure("NIST key unwrap failed"); return R; }
SecureVector<byte> rfc3394_keywrap(const MemoryRegion<byte>& key, const SymmetricKey& kek, Algorithm_Factory& af) { if(key.size() % 8 != 0) throw std::invalid_argument("Bad input key size for NIST key wrap"); std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af)); aes->set_key(kek); const size_t n = key.size() / 8; SecureVector<byte> R((n + 1) * 8); SecureVector<byte> A(16); for(size_t i = 0; i != 8; ++i) A[i] = 0xA6; copy_mem(&R[8], key.begin(), key.size()); for(size_t j = 0; j <= 5; ++j) { for(size_t i = 1; i <= n; ++i) { const u32bit t = (n * j) + i; copy_mem(&A[8], &R[8*i], 8); aes->encrypt(&A[0]); copy_mem(&R[8*i], &A[8], 8); byte t_buf[4] = { 0 }; store_be(t, t_buf); xor_buf(&A[4], &t_buf[0], 4); } } copy_mem(&R[0], &A[0], 8); return R; }
uint64_t ARMGNULDBackend::emitSectionData(const Output& pOutput, const LDSection& pSection, const MCLDInfo& pInfo, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); ELFFileFormat* file_format = getOutputFormat(pOutput); if (&pSection == m_pAttributes) { // FIXME: Currently Emitting .ARM.attributes directly from the input file. const llvm::MCSectionData* sect_data = pSection.getSectionData(); assert(sect_data && "Emit .ARM.attribute failed, MCSectionData doesn't exist!"); uint8_t* start = llvm::cast<MCRegionFragment>( sect_data->getFragmentList().front()).getRegion().start(); memcpy(pRegion.start(), start, pRegion.size()); return pRegion.size(); } if (&pSection == &(file_format->getPLT())) { assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); uint64_t result = m_pPLT->emit(pRegion); return result; } if (&pSection == &(file_format->getGOT())) { assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!"); uint64_t result = m_pGOT->emit(pRegion); return result; } llvm::report_fatal_error(llvm::Twine("Unable to emit section `") + pSection.name() + llvm::Twine("'.\n")); return 0x0; }
uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); const ELFFileFormat* FileFormat = getOutputFormat(); assert(FileFormat && "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); unsigned int EntrySize = 0; uint64_t RegionSize = 0; if (&pSection == &(FileFormat->getPLT())) { assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); unsigned char* buffer = pRegion.getBuffer(); m_pPLT->applyPLT0(); m_pPLT->applyPLT1(); X86PLT::iterator it = m_pPLT->begin(); unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); RegionSize += plt0_size; ++it; PLTEntryBase* plt1 = 0; X86PLT::iterator ie = m_pPLT->end(); while (it != ie) { plt1 = &(llvm::cast<PLTEntryBase>(*it)); EntrySize = plt1->size(); memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); RegionSize += EntrySize; ++it; } } else if (&pSection == &(FileFormat->getGOT())) { RegionSize += emitGOTSectionData(pRegion); } else if (&pSection == &(FileFormat->getGOTPLT())) { RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); } else { fatal(diag::unrecognized_output_sectoin) << pSection.name() << "*****@*****.**"; } return RegionSize; }
uint64_t AArch64GNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); const ELFFileFormat* file_format = getOutputFormat(); if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { uint64_t result = m_pPLT->emit(pRegion); return result; } if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { uint64_t result = m_pGOT->emit(pRegion); return result; } if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { uint64_t result = m_pGOT->emit(pRegion); return result; } return pRegion.size(); }
/// emit void ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const { if (pRegion.size() < pSection.size()) { llvm::report_fatal_error(llvm::Twine("the given memory is smaller") + llvm::Twine(" than the section's demaind.\n")); } uint8_t* address = (uint8_t*)pRegion.begin(); EntryListType::const_iterator entry, entryEnd = m_NeedList.end(); for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) address += (*entry)->emit(address); entryEnd = m_EntryList.end(); for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) address += (*entry)->emit(address); }
uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); const ELFFileFormat* file_format = getOutputFormat(); if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { return m_pGOT->emit(pRegion); } if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { return m_pPLT->emit(pRegion); } if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) { return m_pGOTPLT->emit(pRegion); } fatal(diag::unrecognized_output_sectoin) << pSection.name() << "*****@*****.**"; return 0; }
/* * Encode a message */ SecureVector<byte> EME::encode(const MemoryRegion<byte>& msg, size_t key_bits, RandomNumberGenerator& rng) const { return pad(&msg[0], msg.size(), key_bits, rng); }
/************************************************* * Decode a BigInt * *************************************************/ BigInt BigInt::decode(const MemoryRegion<byte>& buf, Base base) { return BigInt::decode(buf, buf.size(), base); }
virtual void update(const MemoryRegion &in) { if(!in.isSecure()) secure = false; md5_append(&md5, (const md5_byte_t *)in.data(), in.size()); }
/* * Process a full message at once */ void Pipe::process_msg(const MemoryRegion<byte>& input) { process_msg(input.begin(), input.size()); }
/* * Write into a Pipe */ void Pipe::write(const MemoryRegion<byte>& input) { write(&input[0], input.size()); }
/* * Decode a message */ SecureVector<byte> EME::decode(const MemoryRegion<byte>& msg, size_t key_bits) const { return unpad(&msg[0], msg.size(), key_bits); }
uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); const ELFFileFormat* file_format = getOutputFormat(); if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) { uint64_t result = m_pPLT->emit(pRegion); return result; } if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) { uint64_t result = m_pGOT->emit(pRegion); return result; } if (&pSection == m_pAttributes) { return attribute().emit(pRegion); } // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab // directly from the input file. const SectionData* sect_data = pSection.getSectionData(); SectionData::const_iterator frag_iter, frag_end = sect_data->end(); uint8_t* out_offset = pRegion.begin(); for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { size_t size = frag_iter->size(); switch(frag_iter->getKind()) { case Fragment::Fillment: { const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); if (0 == fill_frag.getValueSize()) { // virtual fillment, ignore it. break; } memset(out_offset, fill_frag.getValue(), fill_frag.size()); break; } case Fragment::Region: { const RegionFragment& region_frag = llvm::cast<RegionFragment>(*frag_iter); const char* start = region_frag.getRegion().begin(); memcpy(out_offset, start, size); break; } case Fragment::Alignment: { const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); uint64_t count = size / align_frag.getValueSize(); switch (align_frag.getValueSize()) { case 1u: std::memset(out_offset, align_frag.getValue(), count); break; default: llvm::report_fatal_error( "unsupported value size for align fragment emission yet.\n"); break; } // end switch break; } case Fragment::Null: { assert(0x0 == size); break; } default: llvm::report_fatal_error("unsupported fragment type.\n"); break; } // end switch out_offset += size; } // end for return pRegion.size(); }
/* * Process a handshake message */ void TLS_Server::process_handshake_msg(Handshake_Type type, const MemoryRegion<byte>& contents) { rng.add_entropy(&contents[0], contents.size()); if(state == 0) throw Unexpected_Message("Unexpected handshake message"); if(active && (type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2)) { delete state; state = 0; writer.alert(WARNING, NO_RENEGOTIATION); return; } if(type != HANDSHAKE_CCS && type != FINISHED) { if(type != CLIENT_HELLO_SSLV2) { state->hash.update(static_cast<byte>(type)); const size_t record_length = contents.size(); for(size_t i = 0; i != 3; i++) state->hash.update(get_byte<u32bit>(i+1, record_length)); } state->hash.update(contents); } if(type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2) { server_check_state(type, state); state->client_hello = new Client_Hello(contents, type); client_requested_hostname = state->client_hello->hostname(); state->version = choose_version(state->client_hello->version(), policy.min_version()); writer.set_version(state->version); reader.set_version(state->version); state->server_hello = new Server_Hello(rng, writer, policy, cert_chain, *(state->client_hello), state->version, state->hash); state->suite = CipherSuite(state->server_hello->ciphersuite()); if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) { // FIXME: should choose certs based on sig type state->server_certs = new Certificate(writer, cert_chain, state->hash); } state->kex_priv = PKCS8::copy_key(*private_key, rng); if(state->suite.kex_type() != TLS_ALGO_KEYEXCH_NOKEX) { if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_RSA) { state->kex_priv = new RSA_PrivateKey(rng, policy.rsa_export_keysize()); } else if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_DH) { state->kex_priv = new DH_PrivateKey(rng, policy.dh_group()); } else throw Internal_Error("TLS_Server: Unknown ciphersuite kex type"); state->server_kex = new Server_Key_Exchange(rng, writer, state->kex_priv, private_key, state->client_hello->random(), state->server_hello->random(), state->hash); } if(policy.require_client_auth()) { state->do_client_auth = true; throw Internal_Error("Client auth not implemented"); // FIXME: send client auth request here } state->server_hello_done = new Server_Hello_Done(writer, state->hash); } else if(type == CERTIFICATE) { server_check_state(type, state); // FIXME: process this } else if(type == CLIENT_KEX) { server_check_state(type, state); state->client_kex = new Client_Key_Exchange(contents, state->suite, state->version); SecureVector<byte> pre_master = state->client_kex->pre_master_secret(rng, state->kex_priv, state->server_hello->version()); state->keys = SessionKeys(state->suite, state->version, pre_master, state->client_hello->random(), state->server_hello->random()); } else if(type == CERTIFICATE_VERIFY) { server_check_state(type, state); // FIXME: process this } else if(type == HANDSHAKE_CCS) { server_check_state(type, state); reader.set_keys(state->suite, state->keys, SERVER); state->got_client_ccs = true; } else if(type == FINISHED) { server_check_state(type, state); state->client_finished = new Finished(contents); if(!state->client_finished->verify(state->keys.master_secret(), state->version, state->hash, CLIENT)) throw TLS_Exception(DECRYPT_ERROR, "Finished message didn't verify"); state->hash.update(static_cast<byte>(type)); const size_t record_length = contents.size(); for(size_t i = 0; i != 3; i++) state->hash.update(get_byte<u32bit>(i+1, record_length)); state->hash.update(contents); writer.send(CHANGE_CIPHER_SPEC, 1); writer.flush(); writer.set_keys(state->suite, state->keys, SERVER); state->server_finished = new Finished(writer, state->version, SERVER, state->keys.master_secret(), state->hash); delete state; state = 0; active = true; } else throw Unexpected_Message("Unknown handshake message received"); }
/* * Process a full message at once */ void Pipe::process_msg(const MemoryRegion<byte>& input) { process_msg(&input[0], input.size()); }
uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { if (!pRegion.size()) return 0; const ELFFileFormat* FileFormat = getOutputFormat(); unsigned int EntrySize = 0; uint64_t RegionSize = 0; if ((LinkerConfig::Object != config().codeGenType()) && (!config().isCodeStatic())) { if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { unsigned char* buffer = pRegion.begin(); m_pPLT->applyPLT0(); m_pPLT->applyPLT1(); HexagonPLT::iterator it = m_pPLT->begin(); unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); RegionSize += plt0_size; ++it; PLTEntryBase* plt1 = 0; HexagonPLT::iterator ie = m_pPLT->end(); while (it != ie) { plt1 = &(llvm::cast<PLTEntryBase>(*it)); EntrySize = plt1->size(); memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); RegionSize += EntrySize; ++it; } return RegionSize; } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { RegionSize += emitGOTSectionData(pRegion); return RegionSize; } else if (FileFormat->hasGOTPLT() && (&pSection == &(FileFormat->getGOTPLT()))) { RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); return RegionSize; } } const SectionData* sect_data = pSection.getSectionData(); SectionData::const_iterator frag_iter, frag_end = sect_data->end(); uint8_t* out_offset = pRegion.begin(); for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { size_t size = frag_iter->size(); switch(frag_iter->getKind()) { case Fragment::Fillment: { const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); if (0 == fill_frag.getValueSize()) { // virtual fillment, ignore it. break; } memset(out_offset, fill_frag.getValue(), fill_frag.size()); break; } case Fragment::Region: { const RegionFragment& region_frag = llvm::cast<RegionFragment>(*frag_iter); const char* start = region_frag.getRegion().begin(); memcpy(out_offset, start, size); break; } case Fragment::Alignment: { const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); uint64_t count = size / align_frag.getValueSize(); switch (align_frag.getValueSize()) { case 1u: std::memset(out_offset, align_frag.getValue(), count); break; default: llvm::report_fatal_error( "unsupported value size for align fragment emission yet.\n"); break; } // end switch break; } case Fragment::Null: { assert(0x0 == size); break; } default: llvm::report_fatal_error("unsupported fragment type.\n"); break; } // end switch out_offset += size; } // end for return pRegion.size(); }