[
https://issues.apache.org/jira/browse/HADOOP-11343?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14233786#comment-14233786
]
Jerry Chen commented on HADOOP-11343:
-------------------------------------
{quote}Let me see if I can state this problem differently.{quote}
Exactly.
{quote}This actually isn't a problem if the files are read back exactly as they
are written. But if you try to read file A in two steps, or read file B in one
step, the second block will look corrupted. {quote}
Yes. Logically, if the read follow exact the same pattern of calling caculateIV
at exactly the same positions as write, it still can be decrypted. But that is
very hard assumption and rarely the case in real application.
{quote}Have you tested with both the openssl and java crypto
implementations?{quote}
Currently the test case use JceAesCtrCryptoCodec instance to test calculateIV.
The implementation of calculateIV is common in the base abstract class
AesCtrCryptoCodec and shared by the two CryptoCodec implementations. When a
CryptoCodec has the real need to override calculateIV and it might be question
the override version should be tested with the assumed of test cases. I think
we can make it simple here and keep it is.
{quote}I do believe that you still need to provide an upgrade path. This means
defining a new crypto SUITE and make it the default. Existing files will use
the old SUITE; the upgrade path is to simply copy all the files in an EZ; when
writing the new files the new SUITE will be used and everything will work
out.{quote}
I would think this is not a normal upgrade situation as we think. The existing
encrypted data already has problem to be decrypted with the old SUITE if the
overflow condition descried above happens during encryption.
It is an illusion to expect the old SUITE to deal the problem more properly
than the fixed one. The calling pattern of calculateIV when writing has no
logical relation to the pattern on reading. Just described, unless following
the same pattern, the decryption problem will happen for sure when reading even
with the old SUITE. So I would tend to consider this is a fix of "existing
problem", other than "a revised or improved version".
One benefit to create a new SUITE is that we can distinguish the two types of
data: the data has potential of this problem or the data without. But just as
Andrew pointing, it is a little sticky on this as we are creating two SUITEs
for the same configuration of AES-CTR.
I would prefer another way if we want to distinguish the two type of data: Add
a version attribute to Encrytion file info. This can be addressed with a
separate JIRA.
Happy that we are coming closer on the solution. Thanks you all for review and
comments.
> Overflow is not properly handled in caclulating final iv for AES CTR
> --------------------------------------------------------------------
>
> Key: HADOOP-11343
> URL: https://issues.apache.org/jira/browse/HADOOP-11343
> Project: Hadoop Common
> Issue Type: Bug
> Components: security
> Affects Versions: 2.6.0
> Reporter: Jerry Chen
> Assignee: Jerry Chen
> Priority: Blocker
> Attachments: HADOOP-11343.patch
>
>
> In the AesCtrCryptoCodec calculateIV, as the init IV is a random generated 16
> bytes,
> final byte[] iv = new byte[cc.getCipherSuite().getAlgorithmBlockSize()];
> cc.generateSecureRandom(iv);
> Then the following calculation of iv and counter on 8 bytes (64bit) space
> would easily cause overflow and this overflow gets lost. The result would be
> the 128 bit data block was encrypted with a wrong counter and cannot be
> decrypted by standard aes-ctr.
> /**
> * The IV is produced by adding the initial IV to the counter. IV length
> * should be the same as {@link #AES_BLOCK_SIZE}
> */
> @Override
> public void calculateIV(byte[] initIV, long counter, byte[] IV) {
> Preconditions.checkArgument(initIV.length == AES_BLOCK_SIZE);
> Preconditions.checkArgument(IV.length == AES_BLOCK_SIZE);
>
> System.arraycopy(initIV, 0, IV, 0, CTR_OFFSET);
> long l = 0;
> for (int i = 0; i < 8; i++) {
> l = ((l << 8) | (initIV[CTR_OFFSET + i] & 0xff));
> }
> l += counter;
> IV[CTR_OFFSET + 0] = (byte) (l >>> 56);
> IV[CTR_OFFSET + 1] = (byte) (l >>> 48);
> IV[CTR_OFFSET + 2] = (byte) (l >>> 40);
> IV[CTR_OFFSET + 3] = (byte) (l >>> 32);
> IV[CTR_OFFSET + 4] = (byte) (l >>> 24);
> IV[CTR_OFFSET + 5] = (byte) (l >>> 16);
> IV[CTR_OFFSET + 6] = (byte) (l >>> 8);
> IV[CTR_OFFSET + 7] = (byte) (l);
> }
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)