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 groestl512_process_block (const uint8_t block[128], uint8_t hash[8][16], unsigned int n) { uint8_t message[8][16]; uint8_t state[8][16]; memcpy (state, hash, sizeof (state)); for (uint_fast8_t row = 0; row < 8; row++) { for (uint_fast8_t column = 0; column < 16; column++) { message[row][column] = block[column * 8 + row]; state[row][column] ^= message[row][column]; } } for (uint_fast8_t r = 0; r < 14; r++) { /* P (state) */ add_round_constants_p (state, r); sub_bytes (state); shift_bytes_p (state); mix_bytes (state); } for (uint_fast8_t r = 0; r < 14; r++) { /* Q (message) */ add_round_constants_q (message, r); sub_bytes (message); shift_bytes_q (message); mix_bytes (message); } for (uint_fast8_t row = 0; row < 8; row++) { for (uint_fast8_t column = 0; column < 16; column++) { hash[row][column] ^= state[row][column] ^ message[row][column]; } } }
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"); }
// 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 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_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); }
/** * 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); }
// Perform the core key schedule transform on 4 bytes, as part of the key expansion process // http://en.wikipedia.org/wiki/Rijndael_key_schedule#Key_schedule_core void key_schedule_core(byte *a, int i) { byte temp = a[0]; // Rotate the output eight bits to the left a[0]=a[1]; a[1]=a[2]; a[2]=a[3]; a[3]=temp; sub_bytes(a,4); // Apply Rijndael's S-box on all four individual bytes in the output word a[0]^=lookup_rcon[i]; // On just the first (leftmost) byte of the output word, perform the rcon operation with i // as the input, and exclusive or the rcon output with the first byte of the output word }
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); }
// Encrypt a single 128 bit block by a 128 bit key using AES // http://en.wikipedia.org/wiki/Advanced_Encryption_Standard void AES_Encrypt(unsigned char *data, unsigned char *key) { int i; // To count the rounds // Key expansion unsigned char keys[176]; expand_key(key,keys); // First Round xor_round_key(data,keys,0); // Middle rounds for(i=0; i<9; i++) { sub_bytes(data,16); shift_rows(data); mix_cols(data); xor_round_key(data, keys, i+1); } // Final Round sub_bytes(data,16); shift_rows(data); xor_round_key(data, keys, 10); }
// Encrypt a single 128 bit block by a 128 bit key using AES // http://en.wikipedia.org/wiki/Advanced_Encryption_Standard void EncryptAES(byte *msg, byte *key, byte *c) { int i; // To count the rounds // Key expansion byte keys[176]; expand_key(key,keys); // First Round memcpy(c, msg, 16); xor_round_key(c,keys,0); // Middle rounds for(i=0; i<9; i++) { sub_bytes(c,16); shift_rows(c); mix_cols(c); xor_round_key(c, keys, i+1); } // Final Round sub_bytes(c,16); shift_rows(c); xor_round_key(c, keys, 10); }
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 end_hash (block* b) { uint8_t* hash = (uint8_t*)(b->func_data); uint8_t state[8][16]; memcpy (state, hash, sizeof (state)); for (uint_fast8_t r = 0; r < 14; r++) { /* P (state) */ add_round_constants_p (state, r); sub_bytes (state); shift_bytes_p (state); mix_bytes (state); } for (uint_fast8_t row = 0; row < 8; row++) { for (uint_fast8_t column = 0; column < 16; column++) { hash[row * 16 + column] ^= state[row][column]; } } }
// 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); }