/* * Square Key Schedule */ void Square::key_schedule(const byte key[], size_t) { SecureVector<u32bit> XEK(36), XDK(36); for(size_t i = 0; i != 4; ++i) XEK[i] = load_be<u32bit>(key, i); for(size_t i = 0; i != 8; ++i) { XEK[4*i+4] = XEK[4*i ] ^ rotate_left(XEK[4*i+3], 8) ^ (0x01000000 << i); XEK[4*i+5] = XEK[4*i+1] ^ XEK[4*i+4]; XEK[4*i+6] = XEK[4*i+2] ^ XEK[4*i+5]; XEK[4*i+7] = XEK[4*i+3] ^ XEK[4*i+6]; for(size_t j = 0; j != 4; ++j) XDK[28 - 4*i + j] = XEK[4*(i+1)+j]; transform(&XEK[4*i]); } for(size_t i = 0; i != 4; ++i) for(size_t j = 0; j != 4; ++j) { ME[4*i+j ] = get_byte(j, XEK[i ]); ME[4*i+j+16] = get_byte(j, XEK[i+32]); MD[4*i+j ] = get_byte(j, XDK[i ]); MD[4*i+j+16] = get_byte(j, XEK[i ]); } EK.copy(&XEK[4], 28); DK.copy(&XDK[4], 28); }
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()); }