int main(int argc, char *argv[]) { /* Set up the key and iv. Do I need to say to not hard code these in a * real application? :-) */ /* A 256 bit key */ unsigned char key[AES_KEY_LENGTH] = { '\0' }; /* A 128 bit IV */ unsigned char iv[AES_IV_LENGTH] = { '\0' }; /* Message to be encrypted */ unsigned char *plaintext = NULL; /* Buffer for ciphertext. Ensure the buffer is long enough for the * ciphertext which may be longer than the plaintext, dependant on the * algorithm and mode */ unsigned char *ciphertext = NULL; int plaintext_len = 0; int ciphertext_len = 0; int i = 0, rem = 0, num_of_blocks = 0; printf("AES file encryption tool. Written by Kevin Neale 2015\n\n"); if (argc < 5 || !argv[1] || !argv[2] || !argv[3] || !argv[4]) { printf("Usage: ./encrypt <in> <out> <key> <iv>\n\n"); printf (" <in> - Filepath to the file to be encrypted\n"); printf(" <out> - Filepath to the file which will contain the encrypted data\n\n"); printf (" <key> - 256 bit key to be used for the encryption represented as a 64 character hex string\n"); printf(" e.g. 471C6ABB3CAD5CD41509F961EDD3A2E08E76F61FF6D63412B79E9D500257A06A\n\n"); printf(" <iv> - 128 bit initialisation vector to be used for the encryption represented as a 32 character hex string\n"); printf(" e.g. 743D32B3BEDEEAF5\n\n"); exit(EXIT_FAILURE); } //Open the input file FILE *in = fopen(argv[1], "r"); if (!in) { printf("Error! Could not open input file\n"); exit(EXIT_FAILURE); } //Open the output file FILE *out = fopen(argv[2], "w"); if (!out) { printf("Error! Could not open output file\n"); exit(EXIT_FAILURE); } //Get key and iv if (get_key(argv[3], key) != 0 || get_iv(argv[4], iv) != 0) { printf("Error! Bad parameters\n"); exit(EXIT_FAILURE); } //Prepare input buffer //Determine lenght of the input and allocate a buffer to store it. fseek(in, 0L, SEEK_END); plaintext_len = ftell(in); printf("length of plaintext: %d\n", plaintext_len); fseek(in, 0L, SEEK_SET); if (plaintext_len <= 0) { printf("Error! Input file is empty\n"); exit(EXIT_FAILURE); } plaintext = malloc(sizeof(char) * plaintext_len); if (!plaintext) { printf("Error! Could not allocate memory for input buffer\n"); exit(EXIT_FAILURE); } memset(plaintext, '\0', sizeof(char) * plaintext_len); //Read the file data into the input buffer fread(plaintext, 1, plaintext_len, in); //Prepare the output buffer //Calculate the length of the input data in blocks (128 bit (32 bytes) for AES). rem = plaintext_len % AES_BLOCK_SIZE; num_of_blocks = (plaintext_len - rem) / AES_BLOCK_SIZE; if (rem != 0) { num_of_blocks++; //Add an extra block as the the input data is not an exact multiple of blocks. } ciphertext_len = num_of_blocks * AES_BLOCK_SIZE; //Total memory to allocate is num of blocks times block size printf("number of blocks: %d\ntotal buffer to allocate: %d\n",num_of_blocks, ciphertext_len); ciphertext = malloc(sizeof(char) * ciphertext_len); if (!ciphertext) { printf("Error! Could not allocate memory for output buffer\n"); exit(EXIT_FAILURE); } memset(ciphertext, '\0', sizeof(char) * ciphertext_len); /* Encrypt the plaintext */ ciphertext_len = encrypt(plaintext, plaintext_len, key, iv, ciphertext); printf("length of ciphertext: %d\n", ciphertext_len); for (i = 0; i < ciphertext_len; i++) { fwrite(&ciphertext[i], sizeof(unsigned char), 1, out); } sync(); //Force output flush free(plaintext); free(ciphertext); fclose(in); fclose(out); /* Clean up */ EVP_cleanup(); ERR_free_strings(); return 0; }
void attacker_send_auth_decrypted(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; gcm_context gcm_context; char iv[16]; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 16 || size2 <= 16 || (size1 != 16 && size1 != 24 && size1 != 32)) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ close gcm_context(&gcm_context); //@ interpret_symmetric_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key); //@ assert cg_key == cg_symmetric_key(?p, ?c); if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES, buffer1, (unsigned int) size1 * 8) == 0) { if (get_iv(havege_state, iv) == 0) { //@ assert crypto_chars(normal, iv, 16, ?ccs_iv); //@ assert chars(buffer2, size2, ?cs2); //@ interpret_auth_encrypted(buffer2, size2); //@ open cryptogram(buffer2, size2, ?ccs2, ?cg_enc); //@ cs_to_ccs_crypto_chars(buffer2, cs2); //@ chars_to_crypto_chars(buffer2, size2); //@ close exists(cg_enc); //@ assert cg_enc == cg_auth_encrypted(?p2, ?c2, ?ccs_output2, ?ccs_iv2); //@ crypto_chars_split(buffer2, 16); if (gcm_auth_decrypt(&gcm_context, (unsigned int) size2 - 16, iv, 16, NULL, 0, buffer2, 16, (void*) buffer2 + 16, buffer3) == 0) { /*@ if (!col) { assert crypto_chars(secret, buffer3, size2 - 16, ?ccs_output); ccs_output == ccs_output2; ccs_iv == ccs_iv2; assert ccs2 == ccs_for_cg(cg_enc); assert [_]pub(cg_enc); assert is_public_auth_decryption_is_public(?proof3, pub, pred); proof3(cg_key, cg_enc); public_crypto_chars(buffer3, size2 - 16); chars_to_crypto_chars(buffer3, size2 - 16); } @*/ zeroize(iv, 16); //@ chars_to_crypto_chars(iv, 16); } //@ crypto_chars_to_chars(buffer3, size2 - 16); net_send(socket, buffer3, (unsigned int) size2 - 16); //@ crypto_chars_to_chars(buffer2, 16); //@ crypto_chars_to_chars((void*) buffer2 + 16, size2 - 16); //@ chars_join(buffer2); } //@ crypto_chars_to_chars(iv, 16); gcm_free(&gcm_context); } //@ open gcm_context(&gcm_context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_key); }
void attacker_send_decrypted(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; aes_context aes_context; char iv[16]; size_t iv_off = 0; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 0 || size2 < MINIMAL_STRING_SIZE || (size1 != 16 && size1 != 24 && size1 != 32)) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ close aes_context(&aes_context); //@ interpret_symmetric_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key); //@ assert cg_key == cg_symmetric_key(?p, ?c); if (aes_setkey_enc(&aes_context, buffer1, (unsigned int) size1 * 8) == 0) { if (get_iv(havege_state, iv) == 0) { //@ assert crypto_chars(normal, iv, 16, ?ccs_iv); //@ interpret_encrypted(buffer2, size2); //@ open cryptogram(buffer2, size2, ?ccs2, ?cg_enc); //@ close cryptogram(buffer2, size2, ccs2, cg_enc); //@ assert cg_enc == cg_encrypted(?p2, ?c2, ?ccs_output2, ?ccs_iv2); //@ structure s = known_value(0, nil); //@ close decryption_pre(true, false, attacker, s, ccs2); int success = aes_crypt_cfb128(&aes_context, AES_DECRYPT, (unsigned int) size2, &iv_off, iv, buffer2, buffer3); if (success == 0) zeroize(iv, 16); //@ if (success == 0) chars_to_crypto_chars(iv, 16); //@ open decryption_post(true, ?garbage, attacker, s, p, c, ?ccs_output); /*@ if (garbage) { assert is_public_key_classifier(?proof, _, _, _); proof(cg_key, p, c, true); decryption_garbage(buffer3, size2, s); } else if (success == 0) { assert crypto_chars(secret, buffer3, size2, ccs_output); assert ccs_output == ccs_output2; assert ccs_iv == ccs_iv2; assert ccs2 == ccs_for_cg(cg_enc); public_ccs_cg(cg_enc); assert [_]pub(cg_enc); assert is_public_decryption_is_public(?proof2, pub, pred); proof2(cg_key, cg_enc); public_crypto_chars(buffer3, size2); chars_to_crypto_chars(buffer3, size2); } @*/ //@ crypto_chars_to_chars(buffer3, size2); net_send(socket, buffer3, (unsigned int) size2); //@ public_cryptogram(buffer2, cg_enc); } aes_free(&aes_context); //@ crypto_chars_to_chars(iv, 16); } //@ open aes_context(&aes_context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_key); }
void attacker_send_auth_encrypted(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; gcm_context gcm_context; char iv[16]; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 0 || size2 <= 16 || size2 > MAX_MESSAGE_SIZE - 16 || (size1 != 16 && size1 != 24 && size1 != 32)) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ assert chars(buffer1, size1, ?cs1); //@ assert chars(buffer2, size2, ?cs2); //@ close gcm_context(&gcm_context); //@ interpret_symmetric_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, cs_to_ccs(cs1), ?cg_key); //@ assert cg_key == cg_symmetric_key(?p, ?c); if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES, buffer1, (unsigned int) size1 * 8) == 0) { if (get_iv(havege_state, iv) == 0) { //@ chars_to_crypto_chars(buffer2, size2); //@ chars_split(buffer3, 16); if (gcm_crypt_and_tag(&gcm_context, GCM_ENCRYPT, (unsigned int) size2, iv, 16, NULL, 0, buffer2, (void*) buffer3 + 16, 16, buffer3) == 0) { /*@ { crypto_chars_to_chars(buffer2, size2); public_chars(buffer2, size2); chars_to_crypto_chars(buffer2, size2); assert exists(?cg_enc); assert is_public_auth_encryption_is_public(?proof2, pub, pred); proof2(cg_enc); assert crypto_chars(secret, buffer3, 16, ?ccs_tag); assert crypto_chars(secret, (void*) buffer3 + 16, size2, ?ccs_enc); public_cg_ccs(cg_enc); public_ccs_split(append(ccs_tag, ccs_enc), 16); take_append(16, ccs_tag, ccs_enc); drop_append(16, ccs_tag, ccs_enc); public_crypto_chars(buffer3, 16); public_crypto_chars((void*) buffer3 + 16, size2); } @*/ net_send(socket, buffer3, (unsigned int) size2 + 16); //@ chars_to_crypto_chars(buffer3, 16); //@ chars_to_crypto_chars((void*) buffer3 + 16, size2); } //@ crypto_chars_to_chars(buffer2, size2); //@ crypto_chars_join(buffer3); //@ crypto_chars_to_chars(buffer3, size2 + 16); } gcm_free(&gcm_context); //@ crypto_chars_to_chars(iv, 16); } //@ open gcm_context(&gcm_context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_key); }
void attacker_send_encrypted(havege_state *havege_state, void* socket) //@ requires attacker_invariant(?pub, ?pred, ?kc, havege_state, socket, ?attacker); //@ ensures attacker_invariant(pub, pred, kc, havege_state, socket, attacker); { int temp; int size1; int size2; char buffer1[MAX_MESSAGE_SIZE]; char buffer2[MAX_MESSAGE_SIZE]; char buffer3[MAX_MESSAGE_SIZE]; aes_context aes_context; size_t iv_off = 0; char iv[16]; //@ open attacker_invariant(pub, pred, kc, havege_state, socket, attacker); size1 = net_recv(socket, buffer1, MAX_MESSAGE_SIZE); size2 = net_recv(socket, buffer2, MAX_MESSAGE_SIZE); if (size1 <= 0 || size2 < MINIMAL_STRING_SIZE || (size1 != 16 && size1 != 24 && size1 != 32)) { //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); return; } //@ close aes_context(&aes_context); //@ interpret_symmetric_key(buffer1, size1); //@ assert cryptogram(buffer1, size1, ?ccs1, ?cg_key); //@ assert cg_key == cg_symmetric_key(?p, ?c); if (aes_setkey_enc(&aes_context, buffer1, (unsigned int) size1 * 8) == 0) { if (get_iv(havege_state, iv) == 0) { //@ assert crypto_chars(normal, iv, 16, ?ccs_iv); //@ chars_to_crypto_chars(buffer2, size2); if (aes_crypt_cfb128(&aes_context, AES_ENCRYPT, (unsigned int) size2, &iv_off, iv, buffer2, buffer3) == 0) { /*@ { assert cryptogram(buffer3, size2, ?ccs_enc, ?cg_enc); assert cg_enc == cg_encrypted(p, c, ?cs2, ccs_iv); assert [_]pub(cg_key); assert is_public_encryption_is_public(?proof2, pub, pred); crypto_chars_to_chars(buffer2, size2); public_chars(buffer2, size2); proof2(cg_enc); public_cryptogram(buffer3, cg_enc); chars_to_crypto_chars(buffer2, size2); } @*/ net_send(socket, buffer3, (unsigned int) size2); } //@ crypto_chars_to_chars(buffer2, size2); } aes_free(&aes_context); //@ open aes_context(&aes_context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_symmetric_key(p, c)); //@ crypto_chars_to_chars(iv, 16); return; } //@ open aes_context(&aes_context); //@ close attacker_invariant(pub, pred, kc, havege_state, socket, attacker); //@ public_cryptogram(buffer1, cg_symmetric_key(p, c)); return; }