예제 #1
0
/*! \brief This function performs ECB encryption on input plain text blocks.
 * \param plainText  pointer to the array containing the plain text bytes
 * \param cipherText pointer to the array where the encrypted cipher output has to be stored
 * \param size       size of the input plain text
 */ 
void ecb_encrypt(uint8_t *plainText, uint8_t *cipherText, uint32_t size)
{
	uint32_t input_block_size = 0;
	uint8_t block_count = 0;

	//Calculate the number of input blocks
	input_block_size = size/AES_BLOCK_SIZE;

	for(block_count = 0;block_count < input_block_size; block_count++){
		//Perform forward cipher for the input blocks
		aes_cipher(plainText+(block_count * AES_BLOCK_SIZE), 
							cipherText+(block_count * AES_BLOCK_SIZE));
	}

}
예제 #2
0
/**
 * This function reads the plaintext file in blocks of 16-bytes, and loads the
 * bytes into the state block. This state block is a 4x4 matrix, however, while
 * the array is row-major order, the bytes are arranged vertically. So for bytes
 * b0, b1, b2,..., b15, the state matrix will look like this:
 *
 * [b0, b4, b8 , b12]
 * [b1, b5, b9 , b13]
 * [b2, b6, b10, b14]
 * [b3, b7, b11, b15]
 * 
 * As such, we read/write the bytes from/to the files sequentially into a 
 * separate buffer, and fill in the state block from there. The cipher then
 * assumes that the state is arranged as above. 
 *
 * @param fdin - File descriptor for the plaintext file. Should be a binary file
 *               that has already been opened for reading.
 * @param fdout - File descriptor for the cipher file, which should be a new 
 *                binary file opened for writing.
 * @param key - Pointer to the encryption key.
 */
bool encrypt_file(FILE *fdin, FILE *fdout, aes_key_t *key) {
  int i, b, num_blocks;
  size_t bytes_read;
  long int file_size;
  uint8_t buffer[18]; /* A little bit of extra, just in case */
  uint8_t **state;
  
  /* Initialize state block on the heap */
  state = (uint8_t**)malloc(4 * sizeof(uint8_t*)); 
  for (i = 0; i < 4; i++)
	state[i] = (uint8_t*)malloc(4); /* Allocate each row */

  /* Determine the size of the file. */
  fseek(fdin, 0L, SEEK_END);
  file_size = ftell(fdin);
  rewind(fdin);

  /* Determine the number of blocks to encrypt */
  num_blocks = file_size / AES_BLOCK_SIZE;
  if (file_size % AES_BLOCK_SIZE) num_blocks++;

  VERBOSE("Size of file: %ld bytes (%d blocks)\n", file_size, num_blocks);

  /* Encrypt each block */
  
  for (b = 0; b < num_blocks; b++) {
	if (flags.verbose) {
	  printf("Encrypting block %d of %d.\r", b+1, num_blocks);
	  fflush(stdin);
	}

	/* Read in next 16 bytes. */
	bytes_read = fread(buffer, sizeof(uint8_t), 16, fdin);
	if (ferror(fdin) != 0) {
	  fprintf(stderr, PROGRAM_NAME ": Error: File read error.\n");
	  return false;
	}

	/* If we did not read a full block, pad with 0's */
	while (bytes_read < 16)
	  buffer[bytes_read++] = 0;
	
	/* Fill state block */
	for (i = 0; i < AES_BLOCK_SIZE; i++)
	  state[i%4][i/4] = buffer[i];
	
	aes_cipher(state, key); /* Run cipher on the current state matrix*/

	/* Get the newly encrypted byte sequence */
	for (i = 0; i < AES_BLOCK_SIZE; i++)
	  buffer[i] = state[i%4][i/4];
	
	/* Write result to the output file */
	if (fwrite(buffer, sizeof(uint8_t), 16, fdout) != 16) {
	  fprintf(stderr, PROGRAM_NAME ": Error: File write error.\n");
	  return false;
	}
  }
  VERBOSE("\n");

  for (i = 0; i < 4; i++)
	free(state[i]);
  free(state);
  
  return true;
}
예제 #3
0
/*! \brief This function performs CFB decryption on input cipher text blocks.
 * \param cipherText  pointer to the array containing the cipher text bytes
 * \param plainText   pointer to the array where the decrypted plain text has to be stored
 * \param init_vector pointer to the array containing the unique initialization vector
 * \param mode        CFB mode in bits - can be 8, 64, 128.
 * \param size        size of the input plain text
 */ 
void cfb_decrypt(uint8_t *cipherText, uint8_t *plainText, uint8_t *init_vector, uint8_t mode, uint32_t size)
{
	uint32_t input_block_size = 0;
	uint8_t block_count = 0, byte_count = 0, cfb_byte = 0;
	uint8_t init_vector_temp[AES_BLOCK_SIZE] = {0};
	uint8_t index1 = 0, index2 = 0;
	bool index2_flag = false;

	/* calculate cfb bytes
	 * cfb_byte = 16 for 128 bit CFB, 
	 * cfb_byte = 8 for 64-bit CFB, 
	 * cfb_byte = 4 for 32-bit CFB,
	 * cfb_byte = 2 for 16-bit CFB,
	 * cfb_byte = 1 for 8-bit CFB
	 */
	cfb_byte = mode/8;

	//Calculate the number of input blocks
	input_block_size = (size / AES_BLOCK_SIZE );

	for(byte_count = 0; byte_count<AES_BLOCK_SIZE; byte_count++){
		//Moving initial vector to a temp array
		init_vector_temp[byte_count] = init_vector[byte_count];
	}

	//Forward cipher of initial vector 1
	aes_cipher(init_vector_temp, plainText); 

	//XOR-ing cipher text 's' bits with output block s bits
	for(byte_count = 0; byte_count < cfb_byte; byte_count++){
		plainText[byte_count] = cipherText[byte_count] ^ plainText[byte_count];
	}

	//Decryption of remaining blocks
	for(block_count = 1;block_count < ((AES_BLOCK_SIZE * input_block_size) / cfb_byte); block_count++){

		index1 = 0;
		//Preparation of Initialization vector for the next round
		for (byte_count = 0; byte_count < AES_BLOCK_SIZE; byte_count++){

			if(block_count < ((AES_BLOCK_SIZE/cfb_byte))+1){

				/* For the first few blocks where initialization vector and cipher output 
				 * is used to generate the init_vector_temp
				 */
				if(byte_count < (16 - (block_count + cfb_byte -1))){
					init_vector_temp[byte_count] = 
							init_vector[byte_count + (cfb_byte + block_count - 1)];
				}else{
					init_vector_temp [byte_count] = cipherText[index1++];
				}
				if (block_count == (AES_BLOCK_SIZE / cfb_byte)){
					index2_flag = true;
				}

			}else{

				/* For the remaining blocks where init_vector_temp is generated from the cipher 
				 * output from the previous block. AES Standard FIPS SP800-38A explains more on 
				 * generation of init_vector for each block in different CFB modes
				 */
				init_vector_temp[byte_count] =  cipherText[(cfb_byte * index2) + byte_count];

			}

		}
		if (index2_flag == true){
			index2 = index2+1;
		}

		//Sending initialization vector to the cipher function to get 16 byte output block
		aes_cipher(init_vector_temp,  (plainText+(block_count * cfb_byte)));

		//XOR-ing cipher text 's' bits with output block s bits
		for(byte_count = 0; byte_count < cfb_byte; byte_count++){
			plainText[(byte_count + (block_count * cfb_byte))] = 
					cipherText[(byte_count + (block_count * cfb_byte))]^
					plainText[(byte_count + (block_count * cfb_byte))];
		}

	}

}
예제 #4
0
파일: main.c 프로젝트: dhuertas/AES
int main(int argc, char *argv[]) {

	uint8_t i;

	/*
	 * Appendix A - Key Expansion Examples
	 */
	 
	/* 128 bits */
	/* uint8_t key[] = {
		0x2b, 0x7e, 0x15, 0x16,
		0x28, 0xae, 0xd2, 0xa6,
		0xab, 0xf7, 0x15, 0x88,
		0x09, 0xcf, 0x4f, 0x3c}; */
	
	/* 192 bits */
	/* uint8_t key[] = {
		0x8e, 0x73, 0xb0, 0xf7,
		0xda, 0x0e, 0x64, 0x52,
		0xc8, 0x10, 0xf3, 0x2b,
		0x80, 0x90, 0x79, 0xe5,
		0x62, 0xf8, 0xea, 0xd2,
		0x52, 0x2c, 0x6b, 0x7b}; */
	
	/* 256 bits */
	/* uint8_t key[] = {
		0x60, 0x3d, 0xeb, 0x10,
		0x15, 0xca, 0x71, 0xbe,
		0x2b, 0x73, 0xae, 0xf0,
		0x85, 0x7d, 0x77, 0x81,
		0x1f, 0x35, 0x2c, 0x07,
		0x3b, 0x61, 0x08, 0xd7,
		0x2d, 0x98, 0x10, 0xa3,
		0x09, 0x14, 0xdf, 0xf4};
	*/
	
	/* uint8_t in[] = {
		0x32, 0x43, 0xf6, 0xa8,
		0x88, 0x5a, 0x30, 0x8d,
		0x31, 0x31, 0x98, 0xa2,
		0xe0, 0x37, 0x07, 0x34}; // 128
	*/

	/*
	 * Appendix C - Example Vectors
	 */

	/* 128 bit key */
	/* uint8_t key[] = {
		0x00, 0x01, 0x02, 0x03, 
		0x04, 0x05, 0x06, 0x07, 
		0x08, 0x09, 0x0a, 0x0b, 
		0x0c, 0x0d, 0x0e, 0x0f}; */
	
	/* 192 bit key */
	/* uint8_t key[] = {
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x10, 0x11, 0x12, 0x13,
		0x14, 0x15, 0x16, 0x17}; */
	
	/* 256 bit key */
	uint8_t key[] = {
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x10, 0x11, 0x12, 0x13,
		0x14, 0x15, 0x16, 0x17,
		0x18, 0x19, 0x1a, 0x1b,
		0x1c, 0x1d, 0x1e, 0x1f};

	uint8_t in[] = {
		0x00, 0x11, 0x22, 0x33,
		0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xaa, 0xbb,
		0xcc, 0xdd, 0xee, 0xff};
	
	uint8_t out[16]; // 128

	uint8_t *w; // expanded key

	w = aes_init(sizeof(key));

	aes_key_expansion(key, w);

	printf("Plaintext message:\n");
	for (i = 0; i < 4; i++) {
		printf("%x %x %x %x ", in[4*i+0], in[4*i+1], in[4*i+2], in[4*i+3]);
	}

	printf("\n");

	aes_cipher(in /* in */, out /* out */, w /* expanded key */);

	printf("Ciphered message:\n");
	for (i = 0; i < 4; i++) {
		printf("%x %x %x %x ", out[4*i+0], out[4*i+1], out[4*i+2], out[4*i+3]);
	}

	printf("\n");

	aes_inv_cipher(out, in, w);

	printf("Original message (after inv cipher):\n");
	for (i = 0; i < 4; i++) {
		printf("%x %x %x %x ", in[4*i+0], in[4*i+1], in[4*i+2], in[4*i+3]);
	}

	printf("\n");

	free(w);

	exit(0);
}