void inv_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, Nr); for (r = Nr-1; r >= 1; r--) { inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, w, r); inv_mix_columns(state); } inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, w, 0); for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { out[i+4*j] = state[Nb*i+j]; } } }
void inv_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 inv_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, n_r); if (DEBUG) { debug_print_key_schedule(key_schedule, n_r); } for (int rnd = 1; rnd < n_r; rnd++) { if (DEBUG) printf("\n\nRound %2d\n", rnd); debug_print_block(state, " Start: "); inv_shift_rows(state); debug_print_block(state, " Shift: "); inv_sub_bytes(state); debug_print_block(state, " Subst: "); add_round_key(state, key_schedule, n_r - rnd); inv_mix_columns(state); debug_print_block(state, " Mxcol: "); debug_print_key_schedule(key_schedule, rnd); } if (DEBUG) printf("\n\nRound 10\n"); debug_print_block(state, " Start: "); inv_shift_rows(state); debug_print_block(state, " Shift: "); inv_sub_bytes(state); debug_print_block(state, " Subst: "); add_round_key(state, key_schedule, 0); debug_print_key_schedule(key_schedule, 10); debug_print_block(state, "\n\nPLAINTEXT\n"); }
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 aes_decrypt(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++) { inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, ctx->sub_key + (i * 16)); inv_mix_columns(state); } inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, ctx->sub_key + (i * 16)); memcpy(out, state, 16); }
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 aes128_ecb_decrypt(uint8_t *plaintext, const uint8_t *key, const uint8_t *ciphertext) { int round; memcpy(plaintext, ciphertext, 16); key_schedule(key, round_keys); add_round_key(plaintext, round_keys + 160); inv_shift_rows(plaintext); inv_sub_bytes(plaintext); for (round = N_ROUNDS - 1; round > 0; round--) { add_round_key(plaintext, round_keys + 16 * round); inv_mix_columns(plaintext); inv_shift_rows(plaintext); inv_sub_bytes(plaintext); } add_round_key(plaintext, round_keys); }
void test_sub_bytes_back() { uint8_t state[16] = { 0x01,0x02,0x03,0x04, 0x05,0x06,0x07,0x08, 0x09,0x0a,0x0b,0x0c, 0x0d,0x0e,0x0f,0x10 }; uint8_t tmp_state[16]; memcpy(tmp_state, state, sizeof(tmp_state)); sub_bytes(tmp_state); inv_sub_bytes(tmp_state); int ret = memcmp(tmp_state, state, sizeof(tmp_state)); CU_ASSERT_EQUAL(ret, 0); }
void test_inv_tbox() { tbox_mixing_bijections_t tbox_mixing_bijections, inv_tbox_mixing_bijections; tbox_t tbox; uint32_t expanded_key[(NR + 1) * 4]; uint8_t state[4][4]; uint8_t state2[4][4]; int round, row, col, i; make_tbox_mixing_bijections(tbox_mixing_bijections, inv_tbox_mixing_bijections); for (i = 0; i < (NR + 1) * 4; ++i) expanded_key[i] = (uint8_t) rand(); /* identity key expansion */ make_inv_tbox(tbox, ISBox, expanded_key, tbox_mixing_bijections); for (round = NR - 1; round != 1; --round) { printf("round: %d \n", round); randomize_state(state); memcpy(&state2[0][0], &state[0][0], 16); /* for validation */ dump_state("State before ", state); inv_shift_rows(state); for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col) { state[row][col] = tbox[round][row][col][(state[row][col])]; } } dump_state("State after TBox ", state); /* validation */ /* The above should be equal to: */ /* 0. mix */ /* 1. addroundkey */ /* 2. subbytes */ /* 3. shiftrows */ for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col) { mul_byte_by_matrix(&state2[row][col], tbox_mixing_bijections[round][row][col], state2[row][col]); } } add_round_key(state2, expanded_key, round+1); inv_sub_bytes(state2, ISBox); inv_shift_rows(state2); dump_state("Validation State ", state2); ASSERT(comp_states(state, state2)); } /* validation for the last round is different */ round = 0; { printf("rounds 9 and 10\n"); randomize_state(state); memcpy(&state2[0][0], &state[0][0], 16); /* for validation */ dump_state("State before ", state); inv_shift_rows(state); for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col) { state[row][col] = tbox[round][row][col][(state[row][col])]; } } dump_state("State after TBox ", state); /* validation */ /* The above should be equal to: */ /* 0. mix */ /* 1. addroundkey */ /* 2. subbytes */ /* 3. shiftrows */ /* 4. addroundkey */ for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col) { mul_byte_by_matrix(&state2[row][col], tbox_mixing_bijections[round][row][col], state2[row][col]); } } add_round_key(state2, expanded_key, 1); inv_sub_bytes(state2, ISBox); inv_shift_rows(state2); add_round_key(state2, expanded_key, 0); /* the last key */ dump_state("Validation State ", state2); ASSERT(comp_states(state, state2)); } free_tbox_mixing_bijections(tbox_mixing_bijections); free_tbox_mixing_bijections(inv_tbox_mixing_bijections); }