[openssl-users] Block Ciphers in XTS mode (AES-XTS) [SOLVED - almost ?]
Dr. Pala
director at openca.org
Wed Apr 6 20:58:05 UTC 2016
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/.. at ....?.
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/.. at ....?.
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/.. at ....?.
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/.. at ....?.
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20160406/39b4b75c/attachment-0001.html>
More information about the openssl-users
mailing list