Skip to contentSkip to conversation

Unaligned CTR mode tests in crypto/testmgr.h

RFC Joel Fernandes 3 participants 6 messages Oct 30, 2013 – Oct 31, 2013 Crypto API

lore
Share & tools
lore
#0 lore raw

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0 power of 2.

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

pr_err("request size is not exact amount of AES blocks\n") or a similar message.

Is this failure considered a bug? How do we fix it?

How were the result output vectors generated, did you use 0 padding? Do we 0 pad the inputs to align in these cases to get correct results?

thanks,

-Joel

maintainer
#1 lore raw
Quoted 11 lines · Joel Fernandes

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0 power of 2.

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

pr_err("request size is not exact amount of AES blocks\n") or a similar message.

Is this failure considered a bug? How do we fix it?

Set your alignmask correctly and the crypto API will align the input buffer for you.

Cheers,

Signature · 3 lines
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#2 lore raw
Quoted 19 lines

-----Original Message-----
From: Herbert Xu [mailto:[email protected]]
Sent: Tuesday, October 29, 2013 8:54 PM
To: Fernandes, Joel
Cc: [email protected]; [email protected]
Subject: Re: [RFC] Unaligned CTR mode tests in crypto/testmgr.h

Quoted 4 lines · Joel Fernandes

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0

power of 2.

Quoted 4 lines

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

Quoted 7 lines
Quoted 1 line

pr_err("request size is not exact amount of AES blocks\n") or a similar

message.

Quoted 2 lines

Is this failure considered a bug? How do we fix it?

Set your alignmask correctly and the crypto API will align the input buffer for you.

Thanks! I'll try this today and follow up with a patch if I can get past the error.

Regards,

-Joel

#3 lore raw
In reply to Joel Fernandes
Quoted 11 lines · Joel Fernandes

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0 power of 2.

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

pr_err("request size is not exact amount of AES blocks\n") or a similar message.

Is this failure considered a bug? How do we fix it?

Counter mode turns block cipher into stream cipher and implementation must handle buffer lengths that do not match the block size of underlying block cipher.

Quoted 3 lines

How were the result output vectors generated, did you use 0 padding? Do we 0 pad the inputs to align in these cases to get correct results?

See crypto/ctr.c:crypto_ctr_crypt_final() how to handle trailing bytes when 'buflen % AES_BLOCK_SIZE != 0'.

Basically, you encrypt the last counter block to generate the last keystream block and xor only the 'buflen % AES_BLOCK_SIZE' bytes of last keystream block with the tail bytes of source buffer:

key_last[0..15] = ENC(K, counter[0..15]);
dst_last[0..trailbytes-1] = src_last[0..trailbytes-1] ^ key_last[0..trailbytes-1]; /* key_last[trailbytes..15] discarded. */

Or if you want to use hardware that only does block-size aligned CTR encryption, you can pad input to block size aligned length, do encryption, and then discard those padding bytes after encryption:

src_padded[0..trailbytes-1] = src_last[0..trailbytes-1] src_padded[trailbytes..15] = /* don't care, can be anything/uninitialized */ src_padded[0..15] = ENC_HW_CTR(src_padded[0..15]); dst_last[0..trailbytes-1] = src_padded[0..trailbytes-1];
/* src_padded[trailbytes..15] discarded. */

Here, ENC_HW_CTR(in) internally does:
keystream[0..15] = ENC(K, counter[0..15]); INC_CTR(counter); out[0..15] = in[0..15] ^ keystream[0..15];

-Jussi

Quoted 9 lines

thanks,

-Joel
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw
Quoted 41 lines · Jussi Kivilinna
Quoted 11 lines · Joel Fernandes

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0 power of 2.

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

pr_err("request size is not exact amount of AES blocks\n") or a similar message.

Is this failure considered a bug? How do we fix it?

Counter mode turns block cipher into stream cipher and implementation must handle buffer lengths that do not match the block size of underlying block cipher.

Quoted 3 lines

How were the result output vectors generated, did you use 0 padding? Do we 0 pad the inputs to align in these cases to get correct results?

See crypto/ctr.c:crypto_ctr_crypt_final() how to handle trailing bytes when 'buflen % AES_BLOCK_SIZE != 0'.

Basically, you encrypt the last counter block to generate the last keystream block and xor only the 'buflen % AES_BLOCK_SIZE' bytes of last keystream block with the tail bytes of source buffer:

key_last[0..15] = ENC(K, counter[0..15]);
dst_last[0..trailbytes-1] = src_last[0..trailbytes-1] ^ key_last[0..trailbytes-1]; /* key_last[trailbytes..15] discarded. */

Or if you want to use hardware that only does block-size aligned CTR encryption, you can pad input to block size aligned length, do encryption, and then discard those padding bytes after encryption:

src_padded[0..trailbytes-1] = src_last[0..trailbytes-1] src_padded[trailbytes..15] = /* don't care, can be anything/uninitialized */ src_padded[0..15] = ENC_HW_CTR(src_padded[0..15]); dst_last[0..trailbytes-1] = src_padded[0..trailbytes-1];
/* src_padded[trailbytes..15] discarded. */

Quoted 4 lines

Here, ENC_HW_CTR(in) internally does:
keystream[0..15] = ENC(K, counter[0..15]); INC_CTR(counter); out[0..15] = in[0..15] ^ keystream[0..15];

Thanks, I'll try that. Just one question- is it safe to assume the output buffer (req->dst) is capable of holding those many bytes?

In your algorithm above, we're assuming here without allocating explicitly that the output buffer passed to the driver has trailbytes..15 available. Because otherwise we are in danger of introducing a memory leak, if we just assume they are available in the output buffer.

That said, I don't want to allocate new buffer in the driver and then do copying of encrypted data back into the output buffer. Because I did lot of hard work to get rid of such code as it is slower.

thanks,

-Joel

#5 lore raw
Quoted 47 lines · Joel Fernandes
Quoted 41 lines · Jussi Kivilinna
Quoted 11 lines · Joel Fernandes

Hi,

Some tests such as test 5 in AES CTR mode in crypto/testmgr.h have a unaligned input buffer size such as 499 which is not aligned to any > 0 power of 2.

Due to this, omap-aes driver, and I think atmel-aes too error out when encryption is requested for these buffers.

pr_err("request size is not exact amount of AES blocks\n") or a similar message.

Is this failure considered a bug? How do we fix it?

Counter mode turns block cipher into stream cipher and implementation must handle buffer lengths that do not match the block size of underlying block cipher.

Quoted 3 lines

How were the result output vectors generated, did you use 0 padding? Do we 0 pad the inputs to align in these cases to get correct results?

See crypto/ctr.c:crypto_ctr_crypt_final() how to handle trailing bytes when 'buflen % AES_BLOCK_SIZE != 0'.

Basically, you encrypt the last counter block to generate the last keystream block and xor only the 'buflen % AES_BLOCK_SIZE' bytes of last keystream block with the tail bytes of source buffer:

key_last[0..15] = ENC(K, counter[0..15]);
dst_last[0..trailbytes-1] = src_last[0..trailbytes-1] ^ key_last[0..trailbytes-1]; /* key_last[trailbytes..15] discarded. */

Or if you want to use hardware that only does block-size aligned CTR encryption, you can pad input to block size aligned length, do encryption, and then discard those padding bytes after encryption:

src_padded[0..trailbytes-1] = src_last[0..trailbytes-1] src_padded[trailbytes..15] = /* don't care, can be anything/uninitialized */ src_padded[0..15] = ENC_HW_CTR(src_padded[0..15]); dst_last[0..trailbytes-1] = src_padded[0..trailbytes-1];
/* src_padded[trailbytes..15] discarded. */

Quoted 4 lines

Here, ENC_HW_CTR(in) internally does:
keystream[0..15] = ENC(K, counter[0..15]); INC_CTR(counter); out[0..15] = in[0..15] ^ keystream[0..15];

Quoted 7 lines

Thanks, I'll try that. Just one question- is it safe to assume the output buffer (req->dst) is capable of holding those many bytes?

In your algorithm above, we're assuming here without allocating explicitly that the output buffer passed to the driver has trailbytes..15 available. Because otherwise we are in danger of introducing a memory leak, if we just assume they are available in the output buffer.

In above example, I meant src_padded being temporary block-sized buffer to handle the last trailing bytes. I don't think you can assume that req->dst would have this extra space.

Quoted 5 lines

That said, I don't want to allocate new buffer in the driver and then do copying of encrypted data back into the output buffer. Because I did lot of hard work to get rid of such code as it is slower.

Could you handle first 'buflen - buflen % blocksize' bytes as done currently without extra copies and then handle the trailing bytes separately?

-Jussi

Quoted 9 lines

thanks,

-Joel

--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html