/* * Blowfish Decryption */ void Blowfish::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { verify_key_set(m_S.empty() == false); while(blocks >= 2) { uint32_t L0, R0, L1, R1; load_be(in, L0, R0, L1, R1); for(size_t r = 17; r != 1; r -= 2) { L0 ^= m_P[r]; L1 ^= m_P[r]; R0 ^= BFF(L0, m_S); R1 ^= BFF(L1, m_S); R0 ^= m_P[r-1]; R1 ^= m_P[r-1]; L0 ^= BFF(R0, m_S); L1 ^= BFF(R1, m_S); } L0 ^= m_P[1]; R0 ^= m_P[0]; L1 ^= m_P[1]; R1 ^= m_P[0]; store_be(out, R0, L0, R1, L1); in += 2*BLOCK_SIZE; out += 2*BLOCK_SIZE; blocks -= 2; } if(blocks) { uint32_t L, R; load_be(in, L, R); for(size_t r = 17; r != 1; r -= 2) { L ^= m_P[r]; R ^= BFF(L, m_S); R ^= m_P[r-1]; L ^= BFF(R, m_S); } L ^= m_P[1]; R ^= m_P[0]; store_be(out, R, L); } }
/** * AES Key Schedule */ void AES::key_schedule(const byte key[], u32bit length) { static const u32bit RC[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; ROUNDS = (length / 4) + 6; SecureBuffer<u32bit, 64> XEK, XDK; const u32bit X = length / 4; for(u32bit j = 0; j != X; ++j) XEK[j] = load_be<u32bit>(key, j); for(u32bit j = X; j < 4*(ROUNDS+1); j += X) { XEK[j] = XEK[j-X] ^ S(rotate_left(XEK[j-1], 8)) ^ RC[(j-X)/X]; for(u32bit k = 1; k != X; ++k) { if(X == 8 && k == 4) XEK[j+k] = XEK[j+k-X] ^ S(XEK[j+k-1]); else XEK[j+k] = XEK[j+k-X] ^ XEK[j+k-1]; } } for(u32bit j = 0; j != 4*(ROUNDS+1); j += 4) { XDK[j ] = XEK[4*ROUNDS-j ]; XDK[j+1] = XEK[4*ROUNDS-j+1]; XDK[j+2] = XEK[4*ROUNDS-j+2]; XDK[j+3] = XEK[4*ROUNDS-j+3]; } for(u32bit j = 4; j != length + 24; ++j) XDK[j] = TD[SE[get_byte(0, XDK[j])] + 0] ^ TD[SE[get_byte(1, XDK[j])] + 256] ^ TD[SE[get_byte(2, XDK[j])] + 512] ^ TD[SE[get_byte(3, XDK[j])] + 768]; for(u32bit j = 0; j != 4; ++j) { store_be(XEK[j+4*ROUNDS], ME + 4*j); store_be(XEK[j], MD + 4*j); } EK.copy(XEK, length + 24); DK.copy(XDK, length + 24); }
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; }
/* * Blowfish Decryption */ void Blowfish::dec(const byte in[], byte out[]) const { const u32bit* S1 = S + 0; const u32bit* S2 = S + 256; const u32bit* S3 = S + 512; const u32bit* S4 = S + 768; u32bit L = load_be<u32bit>(in, 0); u32bit R = load_be<u32bit>(in, 1); for(u32bit j = 17; j != 1; 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)]; } L ^= P[1]; R ^= P[0]; store_be(out, R, L); }
/* * Square's Inverse Linear Transformation */ void Square::transform(u32bit round_key[4]) { static const byte G[4][4] = { { 0x02, 0x01, 0x01, 0x03 }, { 0x03, 0x02, 0x01, 0x01 }, { 0x01, 0x03, 0x02, 0x01 }, { 0x01, 0x01, 0x03, 0x02 } }; for(u32bit j = 0; j != 4; ++j) { SecureBuffer<byte, 4> A, B; store_be(round_key[j], A); for(u32bit k = 0; k != 4; ++k) for(u32bit l = 0; l != 4; ++l) { const byte a = A[l]; const byte b = G[l][k]; if(a && b) B[k] ^= ALog[(Log[a] + Log[b]) % 255]; } round_key[j] = load_be<u32bit>(B.begin(), 0); } }
std::vector<byte> New_Session_Ticket::serialize() const { std::vector<byte> buf(4); store_be(m_ticket_lifetime_hint, buf.data()); append_tls_length_value(buf, m_ticket, 2); return buf; }
/* * Blowfish Decryption */ void Blowfish::decrypt_n(const byte in[], byte out[], size_t blocks) 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 != blocks; ++i) { u32bit L = load_be<u32bit>(in, 0); u32bit R = load_be<u32bit>(in, 1); for(size_t j = 17; j != 1; 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)]; } L ^= P[1]; R ^= P[0]; store_be(out, R, L); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
/* * Noekeon Encryption */ void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { u32bit A0 = load_be<u32bit>(in, 0); u32bit A1 = load_be<u32bit>(in, 1); u32bit A2 = load_be<u32bit>(in, 2); u32bit A3 = load_be<u32bit>(in, 3); for(size_t j = 0; j != 16; ++j) { A0 ^= RC[j]; theta(A0, A1, A2, A3, EK.data()); A1 = rotate_left(A1, 1); A2 = rotate_left(A2, 5); A3 = rotate_left(A3, 2); gamma(A0, A1, A2, A3); A1 = rotate_right(A1, 1); A2 = rotate_right(A2, 5); A3 = rotate_right(A3, 2); } A0 ^= RC[16]; theta(A0, A1, A2, A3, EK.data()); store_be(out, A0, A1, A2, A3); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
/* * Square's Inverse Linear Transformation */ void Square::transform(u32bit round_key[4]) { static const byte G[4][4] = { { 2, 1, 1, 3 }, { 3, 2, 1, 1 }, { 1, 3, 2, 1 }, { 1, 1, 3, 2 } }; for(size_t i = 0; i != 4; ++i) { byte A[4] = { 0 }, B[4] = { 0 }; store_be(round_key[i], A); for(size_t j = 0; j != 4; ++j) for(size_t k = 0; k != 4; ++k) { const byte a = A[k]; const byte b = G[k][j]; if(a && b) B[j] ^= ALog[(Log[a] + Log[b]) % 255]; } round_key[i] = load_be<u32bit>(B, 0); } }
/* * Write the count bits to the buffer */ void MDx_HashFunction::write_count(uint8_t out[]) { if(COUNT_SIZE < 8) throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); const uint64_t bit_count = m_count * 8; if(BIG_BYTE_ENDIAN) store_be(bit_count, out + COUNT_SIZE - 8); else store_le(bit_count, out + COUNT_SIZE - 8); }
/* * Noekeon Encryption */ void Noekeon::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { verify_key_set(m_DK.empty() == false); #if defined(BOTAN_HAS_NOEKEON_SIMD) if(CPUID::has_simd_32()) { while(blocks >= 4) { simd_decrypt_4(in, out); in += 4 * BLOCK_SIZE; out += 4 * BLOCK_SIZE; blocks -= 4; } } #endif for(size_t i = 0; i != blocks; ++i) { uint32_t A0 = load_be<uint32_t>(in, 0); uint32_t A1 = load_be<uint32_t>(in, 1); uint32_t A2 = load_be<uint32_t>(in, 2); uint32_t A3 = load_be<uint32_t>(in, 3); for(size_t j = 16; j != 0; --j) { theta(A0, A1, A2, A3, m_DK.data()); A0 ^= RC[j]; A1 = rotl<1>(A1); A2 = rotl<5>(A2); A3 = rotl<2>(A3); gamma(A0, A1, A2, A3); A1 = rotr<1>(A1); A2 = rotr<5>(A2); A3 = rotr<2>(A3); } theta(A0, A1, A2, A3, m_DK.data()); A0 ^= RC[0]; store_be(out, A0, A1, A2, A3); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
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; }
/* * MISTY1 Decryption */ void MISTY1::decrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { u16bit B0 = load_be<u16bit>(in, 2); u16bit B1 = load_be<u16bit>(in, 3); u16bit B2 = load_be<u16bit>(in, 0); u16bit B3 = load_be<u16bit>(in, 1); for(size_t j = 0; j != 12; j += 3) { const u16bit* RK = &DK[8 * j]; B2 ^= B3 | RK[0]; B3 ^= B2 & RK[1]; B0 ^= B1 | RK[2]; B1 ^= B0 & RK[3]; u32bit T0, T1; T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3; T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; B0 ^= T1 ^ RK[13]; B1 ^= T0; T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1; T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0; T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; B2 ^= T1 ^ RK[23]; B3 ^= T0; } B2 ^= B3 | DK[96]; B3 ^= B2 & DK[97]; B0 ^= B1 | DK[98]; B1 ^= B0 & DK[99]; store_be(out, B0, B1, B2, B3); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
/* * KASUMI Decryption */ void KASUMI::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { verify_key_set(m_EK.empty() == false); for(size_t i = 0; i != blocks; ++i) { uint16_t B0 = load_be<uint16_t>(in, 0); uint16_t B1 = load_be<uint16_t>(in, 1); uint16_t B2 = load_be<uint16_t>(in, 2); uint16_t B3 = load_be<uint16_t>(in, 3); for(size_t j = 0; j != 8; j += 2) { const uint16_t* K = &m_EK[8*(6-j)]; uint16_t L = B2, R = B3; L = FI(L ^ K[10], K[11]) ^ R; R = FI(R ^ K[12], K[13]) ^ L; L = FI(L ^ K[14], K[15]) ^ R; L ^= (rotl<1>(R) & K[8]); R ^= (rotl<1>(L) | K[9]); R = B0 ^= R; L = B1 ^= L; L ^= (rotl<1>(R) & K[0]); R ^= (rotl<1>(L) | K[1]); R = FI(R ^ K[2], K[3]) ^ L; L = FI(L ^ K[4], K[5]) ^ R; R = FI(R ^ K[6], K[7]) ^ L; B2 ^= L; B3 ^= R; } store_be(out, B0, B1, B2, B3); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
secure_vector<uint8_t> rfc3394_keywrap(const secure_vector<uint8_t>& key, const SymmetricKey& kek) { if(key.size() % 8 != 0) throw Invalid_Argument("Bad input key size for NIST key wrap"); if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) throw Invalid_Argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key wrap"); 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; secure_vector<uint8_t> R((n + 1) * 8); secure_vector<uint8_t> A(16); for(size_t i = 0; i != 8; ++i) A[i] = 0xA6; copy_mem(&R[8], key.data(), key.size()); for(size_t j = 0; j <= 5; ++j) { for(size_t i = 1; i <= n; ++i) { const uint32_t t = static_cast<uint32_t>((n * j) + i); copy_mem(&A[8], &R[8*i], 8); aes->encrypt(A.data()); copy_mem(&R[8*i], &A[8], 8); uint8_t t_buf[4] = { 0 }; store_be(t, t_buf); xor_buf(&A[4], t_buf, 4); } } copy_mem(R.data(), A.data(), 8); return 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; }
/* * KASUMI Decryption */ void KASUMI::decrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { u16bit B0 = load_be<u16bit>(in, 0); u16bit B1 = load_be<u16bit>(in, 1); u16bit B2 = load_be<u16bit>(in, 2); u16bit B3 = load_be<u16bit>(in, 3); for(size_t j = 0; j != 8; j += 2) { const u16bit* K = &m_EK[8*(6-j)]; u16bit L = B2, R = B3; L = FI(L ^ K[10], K[11]) ^ R; R = FI(R ^ K[12], K[13]) ^ L; L = FI(L ^ K[14], K[15]) ^ R; L ^= (rotate_left(R, 1) & K[8]); R ^= (rotate_left(L, 1) | K[9]); R = B0 ^= R; L = B1 ^= L; L ^= (rotate_left(R, 1) & K[0]); R ^= (rotate_left(L, 1) | K[1]); R = FI(R ^ K[2], K[3]) ^ L; L = FI(L ^ K[4], K[5]) ^ R; R = FI(R ^ K[6], K[7]) ^ L; B2 ^= L; B3 ^= R; } store_be(out, B0, B1, B2, B3); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
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; }
/* * CAST-256 Decryption */ void CAST_256::decrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { u32bit A = load_be<u32bit>(in, 0); u32bit B = load_be<u32bit>(in, 1); u32bit C = load_be<u32bit>(in, 2); u32bit D = load_be<u32bit>(in, 3); round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]); round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]); round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]); round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]); round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]); round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]); round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]); round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]); round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]); round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]); round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]); round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]); round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]); round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]); round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]); round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]); round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]); round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]); round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]); round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]); round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]); round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]); round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]); round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]); store_be(out, A, B, C, D); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
/* * CAST-256 Encryption */ void CAST_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { uint32_t A = load_be<uint32_t>(in, 0); uint32_t B = load_be<uint32_t>(in, 1); uint32_t C = load_be<uint32_t>(in, 2); uint32_t D = load_be<uint32_t>(in, 3); round1(C, D, m_MK[ 0], m_RK[ 0]); round2(B, C, m_MK[ 1], m_RK[ 1]); round3(A, B, m_MK[ 2], m_RK[ 2]); round1(D, A, m_MK[ 3], m_RK[ 3]); round1(C, D, m_MK[ 4], m_RK[ 4]); round2(B, C, m_MK[ 5], m_RK[ 5]); round3(A, B, m_MK[ 6], m_RK[ 6]); round1(D, A, m_MK[ 7], m_RK[ 7]); round1(C, D, m_MK[ 8], m_RK[ 8]); round2(B, C, m_MK[ 9], m_RK[ 9]); round3(A, B, m_MK[10], m_RK[10]); round1(D, A, m_MK[11], m_RK[11]); round1(C, D, m_MK[12], m_RK[12]); round2(B, C, m_MK[13], m_RK[13]); round3(A, B, m_MK[14], m_RK[14]); round1(D, A, m_MK[15], m_RK[15]); round1(C, D, m_MK[16], m_RK[16]); round2(B, C, m_MK[17], m_RK[17]); round3(A, B, m_MK[18], m_RK[18]); round1(D, A, m_MK[19], m_RK[19]); round1(C, D, m_MK[20], m_RK[20]); round2(B, C, m_MK[21], m_RK[21]); round3(A, B, m_MK[22], m_RK[22]); round1(D, A, m_MK[23], m_RK[23]); round1(D, A, m_MK[27], m_RK[27]); round3(A, B, m_MK[26], m_RK[26]); round2(B, C, m_MK[25], m_RK[25]); round1(C, D, m_MK[24], m_RK[24]); round1(D, A, m_MK[31], m_RK[31]); round3(A, B, m_MK[30], m_RK[30]); round2(B, C, m_MK[29], m_RK[29]); round1(C, D, m_MK[28], m_RK[28]); round1(D, A, m_MK[35], m_RK[35]); round3(A, B, m_MK[34], m_RK[34]); round2(B, C, m_MK[33], m_RK[33]); round1(C, D, m_MK[32], m_RK[32]); round1(D, A, m_MK[39], m_RK[39]); round3(A, B, m_MK[38], m_RK[38]); round2(B, C, m_MK[37], m_RK[37]); round1(C, D, m_MK[36], m_RK[36]); round1(D, A, m_MK[43], m_RK[43]); round3(A, B, m_MK[42], m_RK[42]); round2(B, C, m_MK[41], m_RK[41]); round1(C, D, m_MK[40], m_RK[40]); round1(D, A, m_MK[47], m_RK[47]); round3(A, B, m_MK[46], m_RK[46]); round2(B, C, m_MK[45], m_RK[45]); round1(C, D, m_MK[44], m_RK[44]); store_be(out, A, B, C, D); in += BLOCK_SIZE; out += BLOCK_SIZE; } }
/* * Finalize an Adler32 Checksum */ void Adler32::final_result(byte output[]) { store_be(output, S2, S1); clear(); }
/* * Finalize an Adler32 Checksum */ void Adler32::final_result(uint8_t output[]) { store_be(output, m_S2, m_S1); clear(); }
void aes_key_schedule(const byte key[], size_t length, secure_vector<u32bit>& EK, secure_vector<u32bit>& DK, secure_vector<byte>& ME, secure_vector<byte>& MD) { static const u32bit RC[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; const size_t rounds = (length / 4) + 6; secure_vector<u32bit> XEK(length + 32), XDK(length + 32); const size_t X = length / 4; for(size_t i = 0; i != X; ++i) XEK[i] = load_be<u32bit>(key, i); for(size_t i = X; i < 4*(rounds+1); i += X) { XEK[i] = XEK[i-X] ^ RC[(i-X)/X] ^ make_u32bit(SE[get_byte(1, XEK[i-1])], SE[get_byte(2, XEK[i-1])], SE[get_byte(3, XEK[i-1])], SE[get_byte(0, XEK[i-1])]); for(size_t j = 1; j != X; ++j) { XEK[i+j] = XEK[i+j-X]; if(X == 8 && j == 4) XEK[i+j] ^= make_u32bit(SE[get_byte(0, XEK[i+j-1])], SE[get_byte(1, XEK[i+j-1])], SE[get_byte(2, XEK[i+j-1])], SE[get_byte(3, XEK[i+j-1])]); else XEK[i+j] ^= XEK[i+j-1]; } } const std::vector<u32bit>& TD = AES_TD(); for(size_t i = 0; i != 4*(rounds+1); i += 4) { XDK[i ] = XEK[4*rounds-i ]; XDK[i+1] = XEK[4*rounds-i+1]; XDK[i+2] = XEK[4*rounds-i+2]; XDK[i+3] = XEK[4*rounds-i+3]; } for(size_t i = 4; i != length + 24; ++i) XDK[i] = TD[SE[get_byte(0, XDK[i])] + 0] ^ TD[SE[get_byte(1, XDK[i])] + 256] ^ TD[SE[get_byte(2, XDK[i])] + 512] ^ TD[SE[get_byte(3, XDK[i])] + 768]; ME.resize(16); MD.resize(16); for(size_t i = 0; i != 4; ++i) { store_be(XEK[i+4*rounds], &ME[4*i]); store_be(XEK[i], &MD[4*i]); } EK.resize(length + 24); DK.resize(length + 24); copy_mem(EK.data(), XEK.data(), EK.size()); copy_mem(DK.data(), XDK.data(), DK.size()); }
void operator= (T a) { BOOST_STATIC_ASSERT(sizeof(T) == N && sizeof(T) <= 8); store_be(m_data, a); }
/* * Copy out the digest */ void SHA_160::copy_out(byte output[]) { for(u32bit j = 0; j != OUTPUT_LENGTH; j += 4) store_be(digest[j/4], output + j); }