Exemplo n.º 1
0
uint64_t NyuziGNULDBackend::emitSectionData(const LDSection& pSection,
                                              MemoryRegion& pRegion) const
{
  assert(pRegion.size() && "Size of MemoryRegion is zero!");

  return pRegion.size();
}
Exemplo n.º 2
0
/*
* 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");
   }
Exemplo n.º 3
0
/*
* 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;
      }
   }
Exemplo n.º 4
0
/*
* 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;
      }
   }
Exemplo n.º 5
0
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;
   }
Exemplo n.º 6
0
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;
}
Exemplo n.º 9
0
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();
}
Exemplo n.º 10
0
/// 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);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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);
   }
Exemplo n.º 13
0
/*************************************************
* 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());
	}
Exemplo n.º 15
0
/*
* Process a full message at once
*/
void Pipe::process_msg(const MemoryRegion<byte>& input)
   {
   process_msg(input.begin(), input.size());
   }
Exemplo n.º 16
0
/*
* Write into a Pipe
*/
void Pipe::write(const MemoryRegion<byte>& input)
   {
   write(&input[0], input.size());
   }
Exemplo n.º 17
0
/*
* Decode a message
*/
SecureVector<byte> EME::decode(const MemoryRegion<byte>& msg,
                               size_t key_bits) const
   {
   return unpad(&msg[0], msg.size(), key_bits);
   }
Exemplo n.º 18
0
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();
}
Exemplo n.º 19
0
/*
* 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");
   }
Exemplo n.º 20
0
/*
* Process a full message at once
*/
void Pipe::process_msg(const MemoryRegion<byte>& input)
   {
   process_msg(&input[0], input.size());
   }
Exemplo n.º 21
0
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();
}