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"); }
/* debug print */ void debug_print_model(RC_model_t *model) { if (model->type == BLOCK_MODEL) debug_print_block(model->block); else if (model->type == GRID_MODEL) debug_print_grid(model->grid); else fatal("unknown model type\n"); }
int main(int argc, char **argv) { int opt, k_flag = 0, p_flag = 0, d_flag = 0; uint8_t *in_block = NULL, *key = NULL; int keylen; // Key length in bits uint8_t n_k; // Key length in bytes uint8_t n_r; // Number of rounds uint8_t **key_schedule; // ======================= // GET KEY LENGTH AS PARAM // ======================= if (DEBUG) printf("INPUT\n"); while ((opt = getopt (argc, argv, "dk:i:")) != -1) { int len_bits = 0; // Length of hex string -> length of bits switch (opt) { case 'd': // Decrypt option d_flag = 1; break; case 'k': len_bits = strlen(optarg) / 2 * 8; // User option to specify key as hex string if (!(len_bits == 128 || len_bits == 192 || len_bits == 256)) exit_with_usage_message(); keylen = len_bits; key = hex_string_to_bytes(optarg); if (DEBUG) printf(" KeyLen: %d\n", keylen); debug_print_block(key, " InKey: "); k_flag = 1; break; case 'i': // Input block (plaintext or ciphertext) len_bits = strlen(optarg) / 2 * 8; if (len_bits != 128) exit_with_usage_message(); in_block = hex_string_to_bytes(optarg); p_flag = 1; break; default: printf (USAGE_MESSAGE); exit(0); } } if (!k_flag || !p_flag) exit_with_usage_message(); // Compute number of rounds and keylen in bytes switch (keylen) { case 128: n_k = 4; n_r = 10; break; case 192: n_k = 6; n_r = 12; break; case 256: n_k = 8; n_r = 14; break; default: printf("keylen is not 128/192/256."); exit(1); } key_schedule = key_expansion(key, n_k, n_r); if (d_flag) inv_cipher(in_block, key_schedule, n_k, n_r); else cipher(in_block, key_schedule, n_k, n_r); }