/* * Modified key schedule used for bcrypt password hashing */ void Blowfish::salted_set_key(const uint8_t key[], size_t length, const uint8_t salt[], size_t salt_length, size_t workfactor) { BOTAN_ARG_CHECK(salt_length > 0 && salt_length % 4 == 0, "Invalid salt length for Blowfish salted key schedule"); if(length > 72) { // Truncate longer passwords to the 72 char bcrypt limit length = 72; } m_P.resize(18); copy_mem(m_P.data(), P_INIT, 18); m_S.resize(1024); copy_mem(m_S.data(), S_INIT, 1024); key_expansion(key, length, salt, salt_length); if(workfactor > 0) { const size_t rounds = static_cast<size_t>(1) << workfactor; for(size_t r = 0; r != rounds; ++r) { key_expansion(key, length, nullptr, 0); key_expansion(salt, salt_length, nullptr, 0); } } }
/* * Convert some data from Base64 */ void Base64_Decoder::write(const byte input[], size_t length) { while(length) { size_t to_copy = std::min<size_t>(length, m_in.size() - m_position); if(to_copy == 0) { m_in.resize(m_in.size()*2); m_out.resize(m_out.size()*2); } copy_mem(&m_in[m_position], input, to_copy); m_position += to_copy; size_t consumed = 0; size_t written = base64_decode(m_out.data(), reinterpret_cast<const char*>(m_in.data()), m_position, consumed, false, m_checking != FULL_CHECK); send(m_out, written); if(consumed != m_position) { copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed); m_position = m_position - consumed; } else m_position = 0; length -= to_copy; input += to_copy; } }
void snd_udp(struct TCB *tp, unsigned char far *data, int count) { if (IP_STUB(tp)->transport != IPPROTO_UDP) { snd_raw_ip(tp, data, count); // RAW_IP_Packet } else { statistics.udpOutDatagrams++; //rprintf("[udp send %d, %d byte]", tp -tcb, count); copy_mem(_DS, (unsigned)IP_S, _DS, (unsigned)IP_STUB(tp), IP_PLEN); UDP_S->source = tp->local_port; UDP_S->length = htons(count + UDP_HLEN); UDP_S->destination = tp->remote_port; copy_mem(_DS, (unsigned)UDP_S + UDP_PLEN, FP_SEG(data), FP_OFF(data), count); statistics.UDP_snd_bytes += count; IP_S->time_to_live = 0; IP_S->checksum = UDP_S->length; UDP_S->checksum = 0; UDP_S->checksum = checksum(&(IP_S->time_to_live), PSEUDO_HLEN + UDP_HLEN + count); snd_ip(IP_S, UDP_HLEN + count); //print_packet(IP_S, UDP_HLEN + count); } clean_udp_tx_buffer(tp); }
/* * Modified key schedule used for bcrypt password hashing */ void Blowfish::eks_key_schedule(const uint8_t key[], size_t length, const uint8_t salt[16], size_t workfactor) { // Truncate longer passwords to the 56 byte limit Blowfish enforces length = std::min<size_t>(length, 55); if(workfactor == 0) throw Invalid_Argument("Bcrypt work factor must be at least 1"); /* * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to * hash a password. This seems like a reasonable upper bound for the * time being. */ if(workfactor > 18) throw Invalid_Argument("Requested Bcrypt work factor " + std::to_string(workfactor) + " too large"); m_P.resize(18); copy_mem(m_P.data(), P_INIT, 18); m_S.resize(1024); copy_mem(m_S.data(), S_INIT, 1024); key_expansion(key, length, salt); const uint8_t null_salt[16] = { 0 }; const size_t rounds = static_cast<size_t>(1) << workfactor; for(size_t r = 0; r != rounds; ++r) { key_expansion(key, length, null_salt); key_expansion(salt, 16, null_salt); } }
/* * Modified key schedule used for bcrypt password hashing */ void Blowfish::eks_key_schedule(const uint8_t key[], size_t length, const uint8_t salt[16], size_t workfactor) { /* * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to * hash a password. This seems like a reasonable upper bound for the * time being. * Bcrypt allows up to work factor 31 (2^31 iterations) */ BOTAN_ARG_CHECK(workfactor >= 4 && workfactor <= 18, "Invalid bcrypt work factor"); if(length > 72) { // Truncate longer passwords to the 72 char bcrypt limit length = 72; } m_P.resize(18); copy_mem(m_P.data(), P_INIT, 18); m_S.resize(1024); copy_mem(m_S.data(), S_INIT, 1024); key_expansion(key, length, salt); const uint8_t null_salt[16] = { 0 }; const size_t rounds = static_cast<size_t>(1) << workfactor; for(size_t r = 0; r != rounds; ++r) { key_expansion(key, length, null_salt); key_expansion(salt, 16, null_salt); } }
size_t CBC_Decryption::process(uint8_t buf[], size_t sz) { const size_t BS = cipher().block_size(); BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); size_t blocks = sz / BS; while(blocks) { const size_t to_proc = std::min(BS * blocks, m_tempbuf.size()); cipher().decrypt_n(buf, m_tempbuf.data(), to_proc / BS); xor_buf(m_tempbuf.data(), state_ptr(), BS); xor_buf(&m_tempbuf[BS], buf, to_proc - BS); copy_mem(state_ptr(), buf + (to_proc - BS), BS); copy_mem(buf, m_tempbuf.data(), to_proc); buf += to_proc; blocks -= to_proc / BS; } return sz; }
/* * Convert some data from hex format */ void Hex_Decoder::write(const byte input[], size_t length) { while(length) { size_t to_copy = std::min<size_t>(length, in.size() - position); copy_mem(&in[position], input, to_copy); position += to_copy; size_t consumed = 0; size_t written = hex_decode(out.data(), reinterpret_cast<const char*>(in.data()), position, consumed, checking != FULL_CHECK); send(out, written); if(consumed != position) { copy_mem(in.data(), in.data() + consumed, position - consumed); position = position - consumed; } else position = 0; length -= to_copy; input += to_copy; } }
/* * Blowfish Key Schedule */ void Blowfish::key_schedule(const uint8_t key[], size_t length) { m_P.resize(18); copy_mem(m_P.data(), P_INIT, 18); m_S.resize(1024); copy_mem(m_S.data(), S_INIT, 1024); key_expansion(key, length, nullptr, 0); }
void aont_unpackage(BlockCipher* cipher, const byte input[], size_t input_len, byte output[]) { const size_t BLOCK_SIZE = cipher->block_size(); if(!cipher->valid_keylength(BLOCK_SIZE)) throw Invalid_Argument("AONT::unpackage: Invalid cipher"); if(input_len < BLOCK_SIZE) throw Invalid_Argument("AONT::unpackage: Input too short"); // The all-zero string which is used both as the CTR IV and as K0 const std::string all_zeros(BLOCK_SIZE*2, '0'); cipher->set_key(SymmetricKey(all_zeros)); SecureVector<byte> package_key(BLOCK_SIZE); SecureVector<byte> buf(BLOCK_SIZE); // Copy the package key (masked with the block hashes) copy_mem(&package_key[0], input + (input_len - BLOCK_SIZE), BLOCK_SIZE); const size_t blocks = ((input_len - 1) / BLOCK_SIZE); // XOR the blocks into the package key bits for(size_t i = 0; i != blocks; ++i) { const size_t left = std::min<size_t>(BLOCK_SIZE, input_len - BLOCK_SIZE * (i+1)); zeroise(buf); copy_mem(&buf[0], input + (BLOCK_SIZE * i), left); for(size_t j = 0; j != sizeof(i); ++j) buf[BLOCK_SIZE - 1 - j] ^= get_byte(sizeof(i)-1-j, i); cipher->encrypt(buf); xor_buf(&package_key[0], buf, BLOCK_SIZE); } Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); pipe.process_msg(input, input_len - BLOCK_SIZE); pipe.read(output, pipe.remaining()); }
/** * @brief Clone all memory for a module * * @param modld - * * <long-description> * * @return <ReturnValue> */ InsLibModlDesc *InsLibCloneModule(InsLibModlDesc *modld) { InsLibModlDesc *modld_clone = NULL; int sz; if (modld) { modld_clone = (InsLibModlDesc *) sysbrk(sizeof(InsLibModlDesc)); if (!modld_clone) { //pseterr(ENOMEM); printk("InsLib: not enough memory for modld_clone\n"); return NULL; } copy_mem((void *) modld_clone, (void *) modld, sizeof(InsLibModlDesc)); if (modld->BusType == InsLibBusTypeCARRIER) { modld_clone->ModuleAddress = InsLibCloneCar(modld->ModuleAddress); } else if (modld->BusType == InsLibBusTypeVME) { modld_clone->ModuleAddress = InsLibCloneVme(modld->ModuleAddress); } else if ((modld->BusType == InsLibBusTypePMC) || (modld->BusType == InsLibBusTypePCI)) { modld_clone->ModuleAddress = InsLibClonePci(modld->ModuleAddress); } if (modld->Extra) { sz = strlen(modld_clone->Extra) +1; modld_clone->Extra = (char *) sysbrk(sz); if (modld_clone->Extra) copy_mem((void *) modld_clone->Extra, (void *) modld->Extra, sz); } if (modld->Isr) { modld_clone->Isr = (InsLibIntrDesc *) sysbrk(sizeof(InsLibIntrDesc)); if (modld_clone->Isr) copy_mem((void *) modld_clone->Isr, (void *)modld->Isr, sizeof(InsLibIntrDesc)); } modld_clone->Next = InsLibCloneModule(modld->Next); return modld_clone; } return NULL; }
void Streebog::compress_64(const uint64_t M[], bool last_block) { uint64_t N = force_le(last_block ? 0ULL : m_count); uint64_t hN[8]; uint64_t A[8]; copy_mem(hN, m_h.data(), 8); hN[0] ^= N; lps(hN); copy_mem(A, hN, 8); for(size_t i = 0; i != 8; ++i) { hN[i] ^= M[i]; } for(size_t i = 0; i < 12; ++i) { for(size_t j = 0; j != 8; ++j) A[j] ^= force_le(STREEBOG_C[i][j]); lps(A); lps(hN); for(size_t j = 0; j != 8; ++j) hN[j] ^= A[j]; } for(size_t i = 0; i != 8; ++i) { m_h[i] ^= hN[i] ^ M[i]; } if(!last_block) { uint64_t carry = 0; for(int i = 0; i < 8; i++) { const uint64_t m = force_le(M[i]); const uint64_t hi = force_le(m_S[i]); const uint64_t t = hi + m; m_S[i] = force_le(t + carry); carry = (t < hi ? 1 : 0) | (t < m ? 1 : 0); } } }
/* * Read from a memory buffer */ size_t DataSource_Memory::read(byte out[], size_t length) { size_t got = std::min<size_t>(source.size() - offset, length); copy_mem(out, &source[offset], got); offset += got; return got; }
/* * Encrypt in XTS mode */ void XTS_Encryption::write(const byte input[], u32bit length) { const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; u32bit copied = std::min(buffer.size() - position, length); buffer.copy(position, input, copied); length -= copied; input += copied; position += copied; if(length == 0) return; encrypt(buffer); if(length > BLOCK_SIZE) { encrypt(buffer + BLOCK_SIZE); while(length > buffer.size()) { encrypt(input); length -= BLOCK_SIZE; input += BLOCK_SIZE; } position = 0; } else { copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE); position = BLOCK_SIZE; } buffer.copy(position, input, length); position += length; }
void copy_fhead_common(Fli_head *sh, Fli_head *dh) { /* copys all but magic, filesize, or user lock fields between * two fli headers */ copy_mem(OPTR(sh,sizeof(Chunk_id)), OPTR(dh,sizeof(Chunk_id)), FLIH_COMMONSIZE - sizeof(Chunk_id)); }
u32bit read(byte output[], u32bit length) { u32bit copied = std::min(length, end - start); copy_mem(output, buffer + start, copied); start += copied; return copied; }
size_t write(const uint8_t input[], size_t length) { size_t copied = std::min<size_t>(length, m_buffer.size() - m_end); copy_mem(m_buffer.data() + m_end, input, copied); m_end += copied; return copied; }
void Montgomery_Params::square_this(BigInt& x, secure_vector<word>& ws) const { const size_t output_size = 2*m_p_words + 2; if(ws.size() < 2*output_size) ws.resize(2*output_size); word* z_data = &ws[0]; word* ws_data = &ws[output_size]; BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words); bigint_sqr(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), ws_data, output_size); bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size); if(x.size() < output_size) x.grow_to(output_size); copy_mem(x.mutable_data(), z_data, output_size); }
/* * Decrypt in CTS mode */ void CTS_Decryption::write(const byte input[], u32bit length) { u32bit copied = std::min(BUFFER_SIZE - position, length); buffer.copy(position, input, copied); length -= copied; input += copied; position += copied; if(length == 0) return; decrypt(buffer); if(length > BLOCK_SIZE) { decrypt(buffer + BLOCK_SIZE); while(length > 2*BLOCK_SIZE) { decrypt(input); length -= BLOCK_SIZE; input += BLOCK_SIZE; } position = 0; } else { copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE); position = BLOCK_SIZE; } buffer.copy(position, input, length); position += length; }
u32bit write(const byte input[], u32bit length) { u32bit copied = std::min(length, buffer.size() - end); copy_mem(buffer + end, input, copied); end += copied; return copied; }
size_t read(uint8_t output[], size_t length) { size_t copied = std::min(length, m_end - m_start); copy_mem(output, m_buffer.data() + m_start, copied); m_start += copied; return copied; }
std::vector<uint8_t> Datagram_Handshake_IO::format_fragment(const uint8_t fragment[], size_t frag_len, uint16_t frag_offset, uint16_t msg_len, Handshake_Type type, uint16_t msg_sequence) const { std::vector<uint8_t> send_buf(12 + frag_len); send_buf[0] = static_cast<uint8_t>(type); store_be24(&send_buf[1], msg_len); store_be(msg_sequence, &send_buf[4]); store_be24(&send_buf[6], frag_offset); store_be24(&send_buf[9], frag_len); if (frag_len > 0) { copy_mem(&send_buf[12], fragment, frag_len); } return send_buf; }
size_t write(const byte input[], size_t length) { size_t copied = std::min<size_t>(length, buffer.size() - end); copy_mem(buffer.data() + end, input, copied); end += copied; return copied; }
size_t read(byte output[], size_t length) { size_t copied = std::min(length, end - start); copy_mem(output, buffer.data() + start, copied); start += copied; return copied; }
/************************************************* * Read from a memory buffer * *************************************************/ u32bit DataSource_Memory::read(byte out[], u32bit length) { u32bit got = std::min(source.size() - offset, length); copy_mem(out, source + offset, got); offset += got; return got; }
secure_vector<uint8_t> rfc3394_keyunwrap(const secure_vector<uint8_t>& key, const SymmetricKey& kek) { if(key.size() < 16 || key.size() % 8 != 0) throw Invalid_Argument("Bad input key size for NIST key unwrap"); if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) throw Invalid_Argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key unwrap"); const std::string cipher_name = "AES-" + std::to_string(8*kek.size()); std::unique_ptr<BlockCipher> aes(BlockCipher::create_or_throw(cipher_name)); aes->set_key(kek); const size_t n = (key.size() - 8) / 8; secure_vector<uint8_t> R(n * 8); secure_vector<uint8_t> A(16); for(size_t i = 0; i != 8; ++i) A[i] = key[i]; copy_mem(R.data(), &key[8], key.size() - 8); for(size_t j = 0; j <= 5; ++j) { for(size_t i = n; i != 0; --i) { const uint32_t t = static_cast<uint32_t>((5 - j) * n + i); uint8_t t_buf[4] = { 0 }; store_be(t, t_buf); xor_buf(&A[4], t_buf, 4); copy_mem(&A[8], &R[8*(i-1)], 8); aes->decrypt(A.data()); copy_mem(&R[8*(i-1)], &A[8], 8); } } if(load_be<uint64_t>(A.data(), 0) != 0xA6A6A6A6A6A6A6A6) throw Integrity_Failure("NIST key unwrap failed"); return R; }
size_t peek(byte output[], size_t length, size_t offset = 0) { const size_t left = end - start; if(offset >= left) return 0; size_t copied = std::min(length, left - offset); copy_mem(output, buffer.data() + start + offset, copied); return copied; }
size_t peek(uint8_t output[], size_t length, size_t offset = 0) { const size_t left = m_end - m_start; if(offset >= left) return 0; size_t copied = std::min(length, left - offset); copy_mem(output, m_buffer.data() + m_start + offset, copied); return copied; }
state_ptr copy_state(state_ptr s) { state_ptr result = (state_ptr) malloc(sizeof(state_rec)); result->pc = s->pc; result->r = copy_reg(s->r); result->m = copy_mem(s->m); result->cc = s->cc; return result; }
/* * XOR Operation for OctetStrings */ OctetString operator^(const OctetString& k1, const OctetString& k2) { secure_vector<uint8_t> out(std::max(k1.length(), k2.length())); copy_mem(out.data(), k1.begin(), k1.length()); xor_buf(out.data(), k2.begin(), k2.length()); return OctetString(out); }
u32bit peek(byte output[], u32bit length, u32bit offset = 0) { const u32bit left = end - start; if(offset >= left) return 0; u32bit copied = std::min(length, left - offset); copy_mem(output, buffer + start + offset, copied); return copied; }