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_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 test_inv_mix_columns() { uint8_t state[16] = { 0x47,0x37,0x94,0xED, 0x40,0xD4,0xE4,0xA5, 0xA3,0x70,0x3A,0xA6, 0x4C,0x9F,0x42,0xBC }; uint8_t ret_state[16] = { 0x87,0x6E,0x46,0xA6, 0xF2,0x4C,0xE7,0x8C, 0x4D,0x90,0x4A,0xD8, 0x97,0xEC,0xC3,0x95 }; inv_mix_columns(state); int ret = memcmp(ret_state, state, sizeof(ret_state)); CU_ASSERT_EQUAL(ret, 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_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"); }