// Cipher is the main function that encrypts the PlainText. void cipher(int offset) { int i, j, round = 0; //Copy the input PlainText to state array. for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { state[i][j] = temp_buffer[i][j]; } } #ifdef SHIFT_ROWS for (round = 0; round <= nr; round++) shift_rows(); #elif defined(MIX_COLUMNS) for (round = 0; round <= nr; round++) mix_columns(); #elif defined(ADD_ROUND_KEY) for (round = 0; round <= nr; round++) add_round_key(nr); #elif defined(SUB_BYTES) for (round = 0; round <= nr; round++) sub_bytes(); #else // Add the First round key to the state before starting the rounds. add_round_key(0); // There will be nr rounds. // The first nr-1 rounds are identical. // These nr-1 rounds are executed in the loop below. for (round = 1; round < nr; round++) { sub_bytes(); shift_rows(); mix_columns(); add_round_key(round); } // The last round is given below. // The MixColumns function is not here in the last round. sub_bytes(); shift_rows(); add_round_key(nr); #endif // The encryption process is over. // Copy the state array to output array. for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { output_file_buffer[offset + i * 4 + j] = state[i][j]; } } }
void cipher(uint8_t *in, uint8_t *out, uint8_t *w) { uint8_t state[4*Nb]; uint8_t r, i, j; for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { state[Nb*i+j] = in[i+4*j]; } } add_round_key(state, w, 0); for (r = 1; r < Nr; r++) { sub_bytes(state); shift_rows(state); mix_columns(state); add_round_key(state, w, r); } sub_bytes(state); shift_rows(state); add_round_key(state, w, Nr); for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { out[i+4*j] = state[Nb*i+j]; } } }
void cipher(uint8_t *in, uint8_t **key_schedule, uint8_t n_k, uint8_t n_r) { uint8_t *state; state = malloc(BLOCK_LENGTH_IN_BYTES * sizeof(uint8_t)); if(state == NULL) { printf("malloc returned NULL in cipher"); exit(1); } memcpy(state, in, BLOCK_LENGTH_IN_BYTES * sizeof(uint8_t)); if (DEBUG) { printf("\nRound 0\n"); debug_print_block(state, " Start: "); } add_round_key(state, key_schedule, 0); if (DEBUG) { debug_print_key_schedule(key_schedule, 0); } for (int rnd = 1; rnd < n_r; rnd++) { if (DEBUG) printf("\n\nRound %2d\n", rnd); debug_print_block(state, " Start: "); sub_bytes(state); debug_print_block(state, " Subst: "); shift_rows(state); debug_print_block(state, " Shift: "); mix_columns(state); debug_print_block(state, " Mxcol: "); add_round_key(state, key_schedule, rnd); debug_print_key_schedule(key_schedule, rnd); } if (DEBUG) printf("\n\nRound 10\n"); debug_print_block(state, " Start: "); sub_bytes(state); debug_print_block(state, " Subst: "); shift_rows(state); debug_print_block(state, " Shift: "); add_round_key(state, key_schedule, n_r); debug_print_key_schedule(key_schedule, 10); debug_print_block(state, "\n\nCIPHER\n"); }
void aes_enc(aes_ctx_t *ctx) { int i; add_roundkey(ctx->state, ctx->expkey, 0); for(i = 1; i < NR; i++) { sub_bytes(ctx->state); shift_rows(ctx->state); mix_columns(ctx->state, FOR_MIX); add_roundkey(ctx->state, ctx->expkey, i); } sub_bytes(ctx->state); shift_rows(ctx->state); add_roundkey(ctx->state, ctx->expkey, NR); }
void encode_block(BYTE* counter, BYTE* dst, BYTE round_key[ROUND_KEY_SIZE][BLOCK_SIZE]){ unsigned char temp[BLOCK_SIZE]; xor_key(counter, temp, round_key[0]); for(int i = 1; i < ROUNDS; i++){ sub_bytes(temp, dst); shift_rows(dst, temp); mix_columns(temp, dst); xor_key(dst, temp, round_key[i]); } sub_bytes(temp,dst); shift_rows(dst,temp); xor_key(temp,dst,round_key[ROUNDS]); }
void aes_dec(aes_ctx_t *ctx) { int i; uint32_t *expkey = ctx->expkey; uint8_t *state = ctx->state; add_roundkey(state, expkey, NR); inv_shift_rows(state); inv_sub_bytes(state); for(i = NR - 1; i > 0; i--) { add_roundkey(state, expkey, i); mix_columns(state, INV_MIX); inv_shift_rows(state); inv_sub_bytes(state); } add_roundkey(state, expkey, 0); }
void lnc_aes_dec(void *context) { lnc_aes_ctx_t *ctx = context; int i; uint32_t *expkey = ctx->expkey; uint8_t *state = ctx->state; add_roundkey(state, expkey, Nr); inv_shift_rows(state); inv_sub_bytes(state); for(i = Nr - 1; i > 0; i--) { add_roundkey(state, expkey, i); mix_columns(state, INV_MIX); inv_shift_rows(state); inv_sub_bytes(state); } add_roundkey(state, expkey, 0); }
void aes_encrypt(aes_ctx *ctx, const byte *in, byte *out) { int i; byte state[16]; memcpy(state, in, 16); add_round_key(state, ctx->sub_key); for (i = 1; i < 10; i++) { sub_bytes(state); shift_rows(state); mix_columns(state); add_round_key(state, ctx->sub_key + (i * 16)); } sub_bytes(state); shift_rows(state); add_round_key(state, ctx->sub_key + (i * 16)); memcpy(out, state, 16); }
void lnc_aes_enc(void *context) { lnc_aes_ctx_t *ctx = context; int i; uint32_t *expkey = ctx->expkey; uint8_t *state = ctx->state; add_roundkey(state, expkey, 0); for(i = 1; i < Nr; i++) { sub_bytes(state); shift_rows(state); mix_columns(state, FOR_MIX); add_roundkey(state, expkey, i); } sub_bytes(state); shift_rows(state); add_roundkey(state, expkey, Nr); }
void test_mix_columns() { uint8_t state[16] = { 0x87,0x6E,0x46,0xA6, 0xF2,0x4C,0xE7,0x8C, 0x4D,0x90,0x4A,0xD8, 0x97,0xEC,0xC3,0x95 }; uint8_t ret_state[16] = { 0x47,0x37,0x94,0xED, 0x40,0xD4,0xE4,0xA5, 0xA3,0x70,0x3A,0xA6, 0x4C,0x9F,0x42,0xBC }; mix_columns(state); int ret = memcmp(ret_state, state, sizeof(ret_state)); CU_ASSERT_EQUAL(ret, 0); }
static void aes_main(aes_key *key, uint8_t *state) { int i = 0; uint8_t rk[16]; create_round_key(key->data, rk); add_round_key(state, rk); for (i = 1; i < key->nbr; i++) { create_round_key(key->data + 16 * i, rk); shift_rows(state); mix_columns(state); add_round_key(state, rk); } create_round_key(key->data + 16 * key->nbr, rk); shift_rows(state); add_round_key(state, rk); }
/** * This function is the overall application of the AES cipher in the context of * a single state block matrix. * * For each state, we perform the four AES functions several times, in what are * referred to as "rounds". The number of rounds we do depends on the size of * the encryption key. */ void aes_cipher(uint8_t **state, aes_key_t *key) { int round, num_rounds; num_rounds = (key->size / 4) + 6; add_round_key(state, 0, key->exp_block); for (round = 1; round < num_rounds; round++) { sub_bytes(state); shift_rows(state); mix_columns(state); add_round_key(state, round, key->exp_block); } /* Don't mix columns on the last round */ sub_bytes(state); shift_rows(state); add_round_key(state, num_rounds, key->exp_block); }
void Aes256::encrypt(unsigned char* buffer) { unsigned char i, rcon; copy_key(); add_round_key(buffer, 0); for (i = 1, rcon = 1; i < NUM_ROUNDS; ++i) { sub_bytes(buffer); shift_rows(buffer); mix_columns(buffer); if (!(i & 1)) expand_enc_key(&rcon); add_round_key(buffer, i); } sub_bytes(buffer); shift_rows(buffer); expand_enc_key(&rcon); add_round_key(buffer, i); }
void Aes256Encoder::Encrypt(MemoryData& rkey, const MemoryData& key,const MemoryData& salt, unsigned char* buffer) { unsigned char i, rcon; copy_key(rkey, key, salt); add_round_key(rkey.MutableData(), buffer, 0); for (i = 1, rcon = 1; i < RoundCount; ++i) { sub_bytes(buffer); shift_rows(buffer); mix_columns(buffer); if (!(i & 1)) expand_enc_key(rkey.MutableData(), &rcon); add_round_key(rkey.MutableData(), buffer, i); } sub_bytes(buffer); shift_rows(buffer); expand_enc_key(rkey.MutableData(), &rcon); add_round_key(rkey.MutableData(), buffer, i); }
void aes128_ecb_encrypt(const uint8_t *plaintext, const uint8_t *key, uint8_t *ciphertext) { int round; memcpy(ciphertext, plaintext, 16); key_schedule(key, round_keys); add_round_key(ciphertext, round_keys); for (round = 1; round < N_ROUNDS; round++) { sub_bytes(ciphertext); shift_rows(ciphertext); mix_columns(ciphertext); add_round_key(ciphertext, round_keys + 16 * round); } sub_bytes(ciphertext); shift_rows(ciphertext); add_round_key(ciphertext, round_keys + 160); }
void test_mix_columns(){ unsigned char block[] = {0x87, 0x6e, 0x46, 0xa6, 0xf2, 0x4c, 0xe7, 0x8c, 0x4d, 0x90, 0x4a, 0xd8, 0x97, 0xec, 0xc3, 0x95, 0x00}, origblock[17]; unsigned char expected[] = {0x47, 0x37, 0x94, 0xed, 0x40, 0xd4, 0xe4, 0xa5, 0xa3, 0x70, 0x3a, 0xa6, 0x4c, 0x9f, 0x42, 0xbc, 0x00}; memcpy(origblock, block, 17); mix_columns(block, 16); print_block(block, 16); printf("\n"); print_block(expected, 16); printf("\n"); assert( bytencmp(block, expected, 16) == 0 ); inv_mix_columns(block, 16); assert( bytencmp(block, origblock, 16) == 0); print_block(block, 16); printf("\n"); }
// Decrypts the input using AES-128 driven by tablefile; stores in output[4][4] void decrypt_block(unsigned char input_block[16], unsigned char output_block[16], unsigned char round_key[44][4], FILE* table, bool first) { unsigned char state[4][4] = { { 0 } }; // Carries state of block through encryption unsigned char* inv_poly = (unsigned char*)calloc(1,4); // Initialize Substitution Boxes unsigned char* s_box = (unsigned char*)calloc(1,256); unsigned char* inv_s_box = (unsigned char*)calloc(1,256); init_s_box(s_box, table); invert_s_box(s_box, inv_s_box); free(s_box); init_poly(inv_poly, table, "INVP="); // Copy input to initital state for(int i=0; i<16; i++) { state[i%4][i/4] = input_block[i]; } // Print initial inputs and key schedule inv_print_state(state, 0, "iinput", first); inv_print_state(&(round_key[4*10]), 0, "ik_sch", first); // Add initial round key add_round_key(state, round_key, 10); // Perform operations for rounds 1 to 9 for(int i=9; i>0; i--) { inv_print_state(state, 10-i, "istart", first); // Inverse Shift Rows inv_shift_rows(state); inv_print_state(state, 10-i, "is_row", first); // Substitute Bytes sub_bytes(state, inv_s_box); inv_print_state(state, 10-i, "is_box", first); // Add Round Key inv_print_state(&(round_key[4*i]), 10-i, "ik_sch", first); add_round_key(state, round_key, i); inv_print_state(state, 10-i, "ik_add", first); // Mix Columns mix_columns(state, inv_poly); } // Final round operations inv_print_state(state, 10, "istart", first); // Shift Rows inv_shift_rows(state); inv_print_state(state, 10, "is_row", first); // Substitute Bytes sub_bytes(state, inv_s_box); inv_print_state(state, 10, "is_box", first); // Add Round Key add_round_key(state, round_key, 0); inv_print_state(&(round_key[4*0]), 10, "ik_sch", first); // Store final state value in output_block, done for(int i=0; i<16; i++) { output_block[i] = state[i%4][i/4]; } inv_print_state(state, 10, "ioutput", first); free(inv_poly); free(inv_s_box); }
void testBug(void) { mix_columns(buf); average(); ASSERT(1); }