[openssl-dev] [openssl.org #4429] Cannot decrypt RC4-encrypted CMS object
Blumenthal, Uri - 0553 - MITLL
uri at ll.mit.edu
Tue Mar 15 19:09:36 UTC 2016
First of all - thank you! It is great to see useful capabilities added (I
consider stream ciphers and AEAD modes very useful :). I fully agree that
unsigned CMS is an invitation to trouble. If I understand correctly, the
intended openssl use is “openssl cms -encrypt … | openssl cms -sign …” (or
the other way around :).
$ ./util/shlib_wrap.sh ./apps/openssl req -config apps/openssl.cnf -new
-x509 -newkey rsa:2048 -keyout key.pem -nodes -out cert.pem -days 100
-subj "/CN=RC4 CMS Test"
Generating a 2048 bit RSA private key
..........................................+++
.....+++
writing new private key to 'key.pem'
-----
$ ./util/shlib_wrap.sh ./apps/openssl x509 -in cert.pem -noout -serial
serial=B83C7468CCE8930E
$ echo sesame > data.txt
$ ./util/shlib_wrap.sh ./apps/openssl cms -rc4 -encrypt -binary -in
data.txt -out data.txt.cms -outform DER cert.pem
$ ./util/shlib_wrap.sh ./apps/openssl cms -decrypt -in data.txt.cms
-inform DER -out data2.txt -inkey key.pem -recip cert.pem
$ diff -u data.txt data2.txt
$ openssl asn1parse -inform DER -in data.txt.cms
0:d=0 hl=4 l= 380 cons: SEQUENCE
4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-envelopedData
15:d=1 hl=4 l= 365 cons: cont [ 0 ]
. . . . . . .
90:d=5 hl=4 l= 256 prim: OCTET STRING [HEX
DUMP]:362DC32CD6520D3765255D9549BEC058766499C0581430E84929419730B08C31C6E78
D22CB8D8C026EEB75203D19148C97F8F73C7066D158E6E85FEA41972B50EB245ACB15C23209
7DD3046901882B95C9AD102F8E34E0E049B4A374F1EF61C48E1F90F95A3F8E2306161AF0882
99F7A4949D706FBF6A92DB8BB5DF293E1B3BA135BAA8E63FE94C0BBD7A29D31AD28E9137D66
41CF7490257BEE23161A478B6FCBDEE05B1578592272335713196C3F26139A41B76A3EA1371
FA875A4DD09C150D4674AF7A399F886A09D245EE1A81AEC8A96B4647C712D366A0FBC7964FE
C6EF69A076CB58A81ED8DBD466FAA1E9CD072C8242B5D68F3CDB95C5CF04AFE71795
350:d=3 hl=2 l= 32 cons: SEQUENCE
352:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
363:d=4 hl=2 l= 10 cons: SEQUENCE
365:d=5 hl=2 l= 8 prim: OBJECT :rc4
375:d=4 hl=2 l= 7 prim: cont [ 0 ]
$
The only problem - now I have one test failing:
../test/recipes/80-test_ca.t .............. ok
../test/recipes/80-test_cms.t ............. 2/4
# Failed test 'encrypted content test streaming PEM format, 128 bit
RC2 key'
# at ../test/recipes/80-test_cms.t line 418.
# Failed test 'encrypted content test streaming PEM format, 40 bit
RC2 key'
# at ../test/recipes/80-test_cms.t line 418.
# Looks like you failed 2 tests of 27.
../test/recipes/80-test_cms.t ............. 3/4
# Failed test 'CMS <=> CMS consistency tests
# '
# at ../test/recipes/80-test_cms.t line 423.
../test/recipes/80-test_cms.t ............. 4/4 # Looks like you failed 1
test of 4.
../test/recipes/80-test_cms.t ............. Dubious, test returned 1
(wstat 256, 0x100)
Failed 1/4 subtests
../test/recipes/80-test_ct.t .............. Ok
I wonder how difficult would it be to add AEAD support, considering that
they (usually) can take 96-bit nonce (treated as IV), and the
authentication tag often is just appended to the ciphertext (and expected
at the end of the ciphertext during decryption).
--
Regards,
Uri Blumenthal
On 3/15/16, 3:47 , "openssl-dev on behalf of Viktor Dukhovni"
<openssl-dev-bounces at openssl.org on behalf of openssl-users at dukhovni.org>
wrote:
>On Tue, Mar 15, 2016 at 06:33:32AM +0000, Viktor Dukhovni wrote:
>
>> This is completely untested, may not even compile! Enjoy.
>
>It does seem to work, so one key remaining questions is whether it
>is interoperable:
>
> $ ./util/shlib_wrap.sh ./apps/openssl req -config apps/openssl.cnf
>-new -x509 -newkey rsa:2048 -keyout key.pem -nodes -out cert.pem -days
>100 -subj "/CN=RC4 CMS Test"
> <copious output>
> $ ./util/shlib_wrap.sh ./apps/openssl x509 -in cert.pem -noout -serial
> serial=ACD5DEDE758B9AA6
> $ echo sesame > data.txt
> $ ./util/shlib_wrap.sh ./apps/openssl cms -rc4 -encrypt -binary -in
>data.txt -out data.txt.cms -outform DER cert.pem
> $ ./util/shlib_wrap.sh ./apps/openssl cms -decrypt -in data.txt.cms
>-inform DER -out data2.txt -inkey key.pem -recip cert.pem
> $ diff -u data.txt data2.txt
> <no output>
> $ openssl asn1parse -inform DER -in data.txt.cms
> 0:d=0 hl=4 l= 380 cons: SEQUENCE
> 4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-envelopedData
> 15:d=1 hl=4 l= 365 cons: cont [ 0 ]
> 19:d=2 hl=4 l= 361 cons: SEQUENCE
> 23:d=3 hl=2 l= 1 prim: INTEGER :00
> 26:d=3 hl=4 l= 320 cons: SET
> 30:d=4 hl=4 l= 316 cons: SEQUENCE
> 34:d=5 hl=2 l= 1 prim: INTEGER :00
> 37:d=5 hl=2 l= 36 cons: SEQUENCE
> 39:d=6 hl=2 l= 23 cons: SEQUENCE
> 41:d=7 hl=2 l= 21 cons: SET
> 43:d=8 hl=2 l= 19 cons: SEQUENCE
> 45:d=9 hl=2 l= 3 prim: OBJECT :commonName
> 50:d=9 hl=2 l= 12 prim: UTF8STRING :RC4 CMS Test
> 64:d=6 hl=2 l= 9 prim: INTEGER :ACD5DEDE758B9AA6
> 75:d=5 hl=2 l= 13 cons: SEQUENCE
> 77:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
> 88:d=6 hl=2 l= 0 prim: NULL
> 90:d=5 hl=4 l= 256 prim: OCTET STRING [HEX
>DUMP]:70BD8B31ACD24F8184A54AF52446D10898DC09E4636456B8E14B3073701CAD5226C0
>AA03C0AD45B7056DB0A10F01487DC4DE0D35FDE7291875D665DEBB76049C6D660C885A0119
>49A051874DF0CCEA181F9D60BC6BB8BD989B69900E917CCE170F60A34DC77A0EEFB935E135
>78F3AC9703AE02D972F853DBB3302BEB28F1F8E54964E7528E9E24EEA6950535EF2D1027C3
>1CCAEB1FAB8F454ADBEB1DB9FD2A0F61F276498E64931483FDD40E90DD956BF991C3524C9E
>DA70211A256BEEFED941474B26ED7A4516873A12240C505813B6BD6EDFE6ED367FEAC86AEC
>2602A8E1C0C5ACE9C2745FA1B6702F1550FD1ECE322CD7F165DA621E984F1186CA981829AE
> 350:d=3 hl=2 l= 32 cons: SEQUENCE
> 352:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
> 363:d=4 hl=2 l= 10 cons: SEQUENCE
> 365:d=5 hl=2 l= 8 prim: OBJECT :rc4
> 375:d=4 hl=2 l= 7 prim: cont [ 0 ]
> $ tail -c8 data.txt.cms | od -tx1
> 0000000 07 c3 e2 69 a0 ab 3b ec
> 0000010
>
>That said, stream ciphers with unsigned CMS are especially unsafe.
>Since the payload has no MAC or padding of any kind, it is trivial
>to XOR any desired mask into the received plaintext:
>
> $ < data.txt.cms perl -e '
> ($a, $b) = map { unpack("Q", "0$_\n") } qw(sesame unsafe);
> $/ = undef; $cms = <STDIN>;
> substr($cms, -8) = pack("Q", unpack("Q", substr($cms, -8)) ^ $a ^ $b);
> print $cms' > data.txt.cms2
> $ ./util/shlib_wrap.sh ./apps/openssl cms -decrypt -in data.txt.cms2
>-inform DER -out data3.txt -inkey key.pem -recip cert.pem
> $ cat data3.txt
> unsafe
>
>In the above example, a ciphertext-only transformation changes
>'sesame' to 'unsafe'. That, plus RC4's biases, make it unwise in
>this context. At the very least the CMS message MUST be signed,
>and the first 256 bytes should not contain sensitive and yet
>frequently transmitted content.
>
>Don't let your children play with RC4 in CMS.
>
>Of course, unsigned CMS payloads are also vulnerable to silent
>corruption even with block ciphers in CBC mode, XOR of a mask into
>a ciphertext block randomizes the plaintext of that block, but
>makes a predictable change in the plaintext of the next block.
>
>So, don't expect data integrity from unsigned CMS.
>
>--
> Viktor.
>--
>openssl-dev mailing list
>To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4324 bytes
Desc: not available
URL: <http://mta.openssl.org/pipermail/openssl-dev/attachments/20160315/acf134ed/attachment.bin>
More information about the openssl-dev
mailing list