Block Ciphers in XTS mode (AES-XTS)

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Block Ciphers in XTS mode (AES-XTS)

Dr. Pala
Hi all,

I am trying to solve a particular problem related to provide random
access to encrypted files. AFAIK, I have two options. The first is to
use CRT mode (read only) and the second is to use XTS (read and write).

Since I have never used the XTS mode before, does anybody have
experience in using the XTS support in OpenSSL ? Do you have any
particular recommendations for key re-usage in this case (i.e., shall I
use one key per file or can I re-use the same key for different files) ?

Any examples that can guide me through the implementation effort ?

Thanks,
Max

--
Massimiliano Pala, PhD
Director at OpenCA Labs
twitter: @openca

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Block Ciphers in XTS mode (AES-XTS) [SOLVED - almost ?]

Dr. Pala
Hi all,

well.. I did dig a little bit into the implementation code.. I wish who wrote the code would have put some comments to understand how to use the cipher properly.. I hope I did get it right. If anybody is interested in the code-tracking, here's some details:
// Tracking down XTS code in OSSL
//
// crypto/evp/e_evp.c:
//  EVP_AES_XTS_CTX (@line 85)
//   aes_xts_ctrl (supports EVP_CTRL_COPY & EVP_CTRL_INIT only) (@line 1000)
//   aes_xts_init_key (@line 1026)
//   aes_xts_cipher (@line 1088) -> CRYPTO_xts128_encrypt
//   define: BLOCK_CIPHER_custom (@line 1119)
//
// crypto/modes/modes.h: [TODO: check tweak, scratch]
//  XTS128_CONTEXT (@line 144) -> struct xts128_context
//  CRYPTO_xts128_encrypt (@line 146)
//
// crypto/modes/xts128.c:
//   CRYPTO_xts128_encrypt (@line 61)
//
// crypto/modes/modes_lcl.h:
//   struct xts128_context (@line 120)
//
Now, for the interesting part, checking the code I noticed the use of a flag that checks for the size of the data to be encrypted that, for FIPS implementation, should not exceed 2^20 * block-size (in disk encryption that would be the size of the block, I suppose). Anyhow, that inspired me to try to see if, since there is no CRTL to set the size of the block, the implementation assumes that the size of the block is actually passed as the size of the data for each EVP_EncryptUpdate (or EVP_DecryptUpdate)... that seems to be the case. The test code that I generated is capable of decrypting the data at "block" boundaries (code follows).

Although I hoped for a more sophisticated and less error-prone interface, I guess I can work with this (but I hope someone would take charge of adding a little more of complexity to help with the details - maybe that work can also help CTR mode as well to be easier to use for random-access decryption).

Here's an initial (very simple) test implementation:
// Init the CTX
ctx = EVP_CIPHER_CTX_new();

// Set cipher type and mode
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_xts(), NULL, key, iv)

// Total bytes to encrypt
n_ops = 0;
next_op_size = 0;
remains = clear_len;

enc_buf_curr = enc_buf;
clear_buf_curr = clear_buf;

// Encrypt plaintext
while (remains > 0) {

  // Gets the size of the next chunk to be encrypted
  next_op_size = (block_size < remains ? block_size : remains);

  // Performs the encryption
  EVP_EncryptUpdate(ctx, enc_buf_curr, &tmp_len, clear_buf_curr, next_op_size);

  // Updates the number of ops

  n_ops++;

  // Updates the remaining data size to encrypt
  remains -= block_size;

  // Updates the pointer to the next enc buffer space
  enc_buf_curr += tmp_len;

  // Updates the pointer to the next clear buffer space
  clear_buf_curr += block_size;
}

// Finalize the Encryption
EVP_EncryptFinal_ex(ctx, &enc_buf[ret_len], &tmp_len);

// Now we can output the cyphertext (encrypted message)
printf("Ciphertext %d:\n", ret_len);
BIO_dump_fp(stdout, (char *)enc_buf, ret_len);
printf("\n");

// Let's free the OpenSSL CTX structure
EVP_CIPHER_CTX_free(ctx);
Although this works, I noticed that the same data in different blocks result in the same ciphertext (really bad!). For example, with a block size of 64bytes (I know it is very small, but bear with me) and the following clear text input:
 char * text =
    // 128bits per row
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF"
    "0123456789ABCDEF";
The output is as follows:
Encrypted Data:
0000 - bb 56 4d ed dc 56 7c 3d-f8 c5 9d 58 34 d6 68 94   .VM..V|=...X4.h.
0010 - f8 10 03 59 f0 a7 bb 79-e0 9c a3 33 bf b9 48 2d   ...Y...y...3..H-
0020 - 0f 23 c7 56 a8 b0 9c bf-aa a1 0e 4f 11 8b 18 14   .#.V.......O....
0030 - 93 aa ca 02 ea 33 2f 92-b1 40 a2 01 c2 87 3f cc   .....3/..@....?.
0040 - bb 56 4d ed dc 56 7c 3d-f8 c5 9d 58 34 d6 68 94   .VM..V|=...X4.h.
0050 - f8 10 03 59 f0 a7 bb 79-e0 9c a3 33 bf b9 48 2d   ...Y...y...3..H-
0060 - 0f 23 c7 56 a8 b0 9c bf-aa a1 0e 4f 11 8b 18 14   .#.V.......O....
0070 - 93 aa ca 02 ea 33 2f 92-b1 40 a2 01 c2 87 3f cc   .....3/..@....?.
0080 - bb 56 4d ed dc 56 7c 3d-f8 c5 9d 58 34 d6 68 94   .VM..V|=...X4.h.
0090 - f8 10 03 59 f0 a7 bb 79-e0 9c a3 33 bf b9 48 2d   ...Y...y...3..H-
00a0 - 0f 23 c7 56 a8 b0 9c bf-aa a1 0e 4f 11 8b 18 14   .#.V.......O....
00b0 - 93 aa ca 02 ea 33 2f 92-b1 40 a2 01 c2 87 3f cc   .....3/..@....?.
00c0 - bb 56 4d ed dc 56 7c 3d-f8 c5 9d 58 34 d6 68 94   .VM..V|=...X4.h.
00d0 - f8 10 03 59 f0 a7 bb 79-e0 9c a3 33 bf b9 48 2d   ...Y...y...3..H-
00e0 - 0f 23 c7 56 a8 b0 9c bf-aa a1 0e 4f 11 8b 18 14   .#.V.......O....
00f0 - 93 aa ca 02 ea 33 2f 92-b1 40 a2 01 c2 87 3f cc   .....3/..@....?.
Which, for what I know if XTS (that is very little, I admit), this should not be the case.. am I correct ? I was under the impression that the encryption should be tied to the position in the file (or Disk) - i.e., the block number. If so, does anybody know what I am actually missing here ? Am I supposed to, somehow, modify the plaintext before encrypting it (e.g., XOR with the block number ?).

Thanks,
Max

P.S.: I am cross-posting the message also to dev as this might have better chances to get an answer there... ?


On 4/6/16 10:54 AM, Dr. Pala wrote:
Hi all,

I am trying to solve a particular problem related to provide random access to encrypted files. AFAIK, I have two options. The first is to use CRT mode (read only) and the second is to use XTS (read and write).

Since I have never used the XTS mode before, does anybody have experience in using the XTS support in OpenSSL ? Do you have any particular recommendations for key re-usage in this case (i.e., shall I use one key per file or can I re-use the same key for different files) ?

Any examples that can guide me through the implementation effort ?

Thanks,
Max


-- 
Massimiliano Pala, PhD
Director at OpenCA Labs
twitter: @openca

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users