Size of encrypted AES CEK in CMS block When I run

openssl cms -encrypt -aes256 -in sample.der -out wrapped.der -outform DER -recip ecc.crt -keyopt ecdh_kdf_md:sha512


the part of the CMS output which is supposed to have the 256 bit CEK encrypted under the KEK shows to be 40 bytes:

316:d=7  hl=2 l=  40 prim:        OCTET STRING      [HEX DUMP]:FDC50AE5E72BC6D856D9682ACA5B4C2BD23F6B8A35F2E03417E0FE32062B810D3E4DF0048D1C0E2F


I was expecting this to be 48 bytes (32 byte encrypted output + 16 byte padding). It appears the KEK generated from the ECDH operation is not AES256. 

What is the key type of the KEK and algorithm used to encrypt the CEK?



This is the complete CMS message:

0:d=0  hl=4 l= 724 cons: SEQUENCE
4:d=1  hl=2 l=   9 prim:  OBJECT            :pkcs7-envelopedData
15:d=1  hl=4 l= 709 cons:  cont [ 0 ]
19:d=2  hl=4 l= 705 cons:   SEQUENCE
23:d=3  hl=2 l=   1 prim:    INTEGER           :02
26:d=3  hl=4 l= 328 cons:    SET
30:d=4  hl=4 l= 324 cons:     cont [ 1 ]
34:d=5  hl=2 l=   1 prim:      INTEGER           :03
37:d=5  hl=3 l= 151 cons:      cont [ 0 ]
40:d=6  hl=3 l= 148 cons:       cont [ 1 ]
43:d=7  hl=2 l=   9 cons:        SEQUENCE
45:d=8  hl=2 l=   7 prim:         OBJECT            :id-ecPublicKey
54:d=7  hl=3 l= 134 prim:        BIT STRING
191:d=5  hl=2 l=  23 cons:      SEQUENCE
193:d=6  hl=2 l=   6 prim:       OBJECT            :dhSinglePass-stdDH-sha512kdf-scheme
201:d=6  hl=2 l=  13 cons:       SEQUENCE
203:d=7  hl=2 l=   9 prim:        OBJECT            :id-aes256-wrap
214:d=7  hl=2 l=   0 prim:        NULL
216:d=5  hl=3 l= 139 cons:      SEQUENCE
219:d=6  hl=3 l= 136 cons:       SEQUENCE
222:d=7  hl=2 l=  92 cons:        SEQUENCE
224:d=8  hl=2 l=  82 cons:         SEQUENCE
226:d=9  hl=2 l=  41 cons:          SET
228:d=10 hl=2 l=  16 cons:           SEQUENCE
230:d=11 hl=2 l=   3 prim:            OBJECT            :organizationName
235:d=11 hl=2 l=   9 prim:            PRINTABLESTRING   :Widgits Inc
246:d=10 hl=2 l=  21 cons:           SEQUENCE
248:d=11 hl=2 l=   3 prim:            OBJECT            :organizationalUnitName
253:d=11 hl=2 l=  14 prim:            PRINTABLESTRING   :SUB-CA ENC
269:d=9  hl=2 l=  37 cons:          SET
271:d=10 hl=2 l=  16 cons:           SEQUENCE
273:d=11 hl=2 l=   3 prim:            OBJECT            :x500UniqueIdentifier
278:d=11 hl=2 l=   9 prim:            BIT STRING
289:d=10 hl=2 l=  17 cons:           SEQUENCE
291:d=11 hl=2 l=   3 prim:            OBJECT            :commonName
296:d=11 hl=2 l=  10 prim:            PRINTABLESTRING   :ENC CA
308:d=8  hl=2 l=   6 prim:         INTEGER           :333230303032
316:d=7  hl=2 l=  40 prim:        OCTET STRING      [HEX DUMP]:FDC50AE5E72BC6D856D9682ACA5B4C2BD23F6B8A35F2E03417E0FE32062B810D3E4DF0048D1C0E2F
358:d=3  hl=4 l= 366 cons:    SEQUENCE
362:d=4  hl=2 l=   9 prim:     OBJECT            :pkcs7-data
373:d=4  hl=2 l=  29 cons:     SEQUENCE
375:d=5  hl=2 l=   9 prim:      OBJECT            :aes-256-cbc
386:d=5  hl=2 l=  16 prim:      OCTET STRING      [HEX DUMP]:1DD39A70A664EDA8B78EAE1A79D8ECDF
(moved from comment, expanded slightly) 

(AES) Key Wrap is not the same as normal data encryption like CBC or GCM; it does quite a bit of remixing, and adds exactly 64 bits to any AES "plain key" (here 256 + 64 = 320 = 40 bytes) even though it uses the AES algorithm which has a 128-bit data block. See http://tools.ietf.org/html/rfc3394 and the relevant example in section 4.6. 

The KEK is indeed 256 bits in this case, determined by the algorithm id-aes256-wrap, but that key doesn't appear in the message; it is derived from ECDH key agreement, using the originatorkey in the message (in the BITSTRING at offset 54) and the key in the recipient cert identified in the message.

The ECDH key(s) here appear to be on a 521-bit curve, presumably secp521p1, although on looking closer I notice it is not encoded in the AlgorithmIdentifier for originatorkey as is normally the case for encoded public keys. If the ECDH curve were substantially smaller, then the key-agreement strength would be less than 256, which would make the use of a 256-bit CEK in a sense wasted.