> From: owner-openssl-us...@openssl.org On Behalf Of pkumarn
> Sent: Wednesday, 04 April, 2012 05:41

> I need to wrap 512bit key with 256 bit KEK key. When i do 
> this, i am hitting
> seg fault in AES_wrap_key(). When i do gdb, it points to 
> memcpy(). <snip>

> #define KEY512  0
> 
> #if KEY512
>     #define KEYLEN      64
>     #define KEYBITS     512
> #else
>     #define KEYLEN  32
>     #define KEYBITS 256
> #endif

>     #if (!KEY512)
>     static const unsigned char kek[] = {
>       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
>       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
>       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
>       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
>       };
>     #else
>     static const unsigned char kek[] = {
>     0xbc, 0x54, 0xd8, 0xa0, 0x6e, 0xab, 0x3b,
>     0x4c, 0x06, 0xf5, 0xbe, 0x01, 0xc5, 0x77,
>     0x28, 0x3d, 0x92, 0xda, 0xfb, 0xe8, 0x3f,
>     0xe0, 0x59, 0x57, 0xff, 0xbe, 0xfa, 0x5b,
>     0xe0, 0xd4, 0xfb, 0xb7
>     };
>     #endif

>     #if (!KEY512)
>     static const unsigned char key[] = <snip: 32 bytes>
>     #else
>     static const unsigned char key[] = <snip: 64 bytes>
>     #endif
> 
Suggestion: for hardcoded data like this which is supposed 
to be an exact size, it's usually best to verify it is 
the correct size before using it, because it's easy for 
humans to mis-count and/or mistakenly change it. 
In real use of course your key data should not be hardcoded 
(because then it provides no actual security benefit) so 
this issue doesn't arise; instead you should allocate 
the correct size (by declaration or malloc/etc) and get 
correct size data by some other means (e.g. RAND_bytes).

> 
>     int ret, i;
>     unsigned char *otmp, *dtmp;
> 
>     AES_KEY actx, dctx;
>    printf("\n keylen = %d; kebits= %d", KEYLEN, KEYBITS);
> 
Get out of the habit of outputting 'partial' lines (not 
terminated by \n) in C. Sometimes it works and sometimes 
it doesn't. It appears in this case on your system it didn't.
The standard requires complete lines to work (up to possibly 
a reasonable documented length limit) and if they don't (and 
you didn't screw up something else) you can complain to your 
implementor; incomplete lines are formally undefined behavior 
which means the implementation can do anything it likes and 
needn't even document it, although in practice implementors 
try to do something reasonably sane if possible.

>     if (AES_set_encrypt_key(kek, KEYBITS, &actx))
>         printf("\n Error seeting AES key ");
> 
This is the actual error. The KEK is an AES key and can't 
ever be 512 bits. Your declarations above actually define 
kek as 32 bytes = 256 bits for either setting of KEY512, 
which is valid, so use 256 as kek length. Alternatively 
choose a KEK which is another valid AES size and use that size.

>     otmp = (unsigned char *) malloc(sizeof(char) * (KEYLEN+8));
>     dtmp = (unsigned char *) malloc(sizeof(char) * KEYLEN);
> 
Don't cast malloc in C, and in real code check for failure.
Or for a small known size like this don't malloc at all.

>   ret = AES_wrap_key(&actx, default_iv, otmp, key, KEYLEN);
> 
Because AES_set_encrypt_key failed (but you ignored the failure) 
this screws up; it does so differently on different systems, 
and the only system I have where it segfaults (Windows) I can't 
currently debug for 1.0.0. In any case it doesn't work as desired.

>     printf("\n AES wrap ; ret =  %d", ret);
> 
>     if (ret < 0)
>         printf("\n AES wrap key failed");
> 
>     printf("\n Wrapped key : ");
> 
>     for (i = 0; i< (KEYLEN + 8); i++)
>         printf(" %02x", otmp[i]);
> 
> 
>     if (AES_set_decrypt_key(kek, KEYBITS, &dctx))
>         printf("\n Error setting decrypt key ");
> 
Same here.

>     ret = AES_unwrap_key(&dctx, default_iv, dtmp, otmp, ret);
> 
>     printf("\n AES unwrap ; ret = %d", ret);
> 
>     if (ret == 0)
>         printf("\n AES unwrapping failed ");
> 
>     printf("\n Original key : ");
>     for (i = 0; i < KEYLEN ; i++)
>         printf(" %02x", dtmp[i]);
> 
>     printf("\n");
>    free(otmp);
>    free(dtmp);
> 
> }
> 
With set_{en,de}crypt_key fixed it works for me.


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to