Tag mismatch decrypting files encrypted with OpenSSL's AES-CCM

822 views
Skip to first unread message

Anirudh Ramachandran

unread,
Jun 19, 2013, 9:57:10 PM6/19/13
to SJCL discussion
Hello folks,

I've been trying -- unsuccessfully -- to get files encrypted with
OpenSSL's CCM mode to decrypt using SJCL. Both implementations
correctly decrypt files encrypted using themselves (duh!) but I always
find a tag mismatch when trying to interoperate. Note that I'm only
looking for SJCL decryption at the moment.

I'm using a 256-bit key derived from a password using PBKDF2-HMAC-
SHA256, 128-bit zero IV, empty adata, and a 128-bit tag. After
encrypting with OpenSSL, I append the tag to the end of the output as
expected by SJCL. The key derivation works correctly with SJCL but
neither the decrypted output nor the tag matches work.

Any ideas what I could be doing wrong? My code is here:
https://github.com/oakenshield/aes-demo/tree/master/ccm

aes-ccm.cpp -- the OpenSSL-based encrypt/decrypt code. The setting/
getting tag is done as shown in OpenSSL team's own demos [1]. (Needs
Boost Iostreams, Filesystem, and System to compile)

aes-ccm-decrypt.html - The SJCL based decrypt code. The key derivation
works and the 16-byte tag is retrieved correctly from the end of the
output... it just doesn't match SJCL's computed tag. (Uses FileReader
API available in Chrome)

Test files: 'test_encrypted.txt' is 'test.txt' encrypted by the C++
program with a passphrase 'asdfgh123'

Any tips greatly appreciated!

Thanks,
Anirudh

[1] https://github.com/openssl/openssl/blob/master/demos/evp/aesccm.c

Mike Hamburg

unread,
Jun 20, 2013, 2:05:56 AM6/20/13
to sjcl-d...@googlegroups.com
Hi Anirudh,

CCM doesn't really support IVs which are more than 96 bits long. Maybe try a shorter version of the IV?

Cheers,
-- Mike
> --
> You received this message because you are subscribed to the Google Groups "SJCL discussion" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sjcl-discuss...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>

Anirudh Ramachandran

unread,
Jun 20, 2013, 6:04:27 PM6/20/13
to sjcl-d...@googlegroups.com
Hi Mike,

Thanks for the suggestion, but that unfortunately doesn't seem to be the fix.

On another note - are you (or someone else on the list) aware of successful interoperability of SJCL with other implementations of CCM, such as BouncyCastle or Crypto++?

Thanks,
Anirudh

Scott Weber

unread,
Aug 12, 2013, 11:22:12 AM8/12/13
to sjcl-d...@googlegroups.com
Anirudh or Mike,

Has there been any progress on this?  I am in the same situation, but the other way around. 
I created a cipher using the demo web page (http://bitwiseshiftleft.github.io/sjcl/demo/) , but cannot get it to decipher using OpenSSL.

Even more directly, I wrote a basic test routine in C.  I simply take the 16 byte IV and the 256 bit passkey from the demo page, code them into my C program, and pass it directly to the AES_cbc_encrypt function.  Specifically:
         AES_cbc_encrypt(src, dst, len, &aeskey, initVect, AES_DECRYPT);
but the result is that it won't decipher even my original text.

The demo web pages say "SJCL adds a an authentication tag to your message ..."  But doesn't tell me what that tag value is, if it is ciphered or not, or where it is placed (beginning or end)

Any guidance would be appreciated.  My simple code is below  (obvious declarations not pasted to save space)

-Scott Weber


/*  Note: the Key/IV values are correct, I see them in the debugger matching the values from the demo page */

unsigned char key32[] =
    {0x52,0xB0,0x7A,0x77,0x95,0x5E,0x4E,0xCB,0x50,0xBC,0x32,0xDB,0xE7,0x91,0xB0,0x27,
    0x4C,0x2E,0x25,0xB4,0x55,0xC1,0x56,0x2E,0xBA,0x97,0x00,0xB6,0x65,0xF0,0x31,0xBA };


void AES256Decrypt(char *dst, const unsigned char * src, int len) {

    AES_KEY aeskey;
    memcpy(initVect,iv,sizeof(initVect));
    AES_set_decrypt_key((unsigned char *)key32, 32*8, &aeskey);
    AES_cbc_encrypt((unsigned char *)src,(unsigned char *) dst, len, &aeskey, initVect, AES_DECRYPT);
}

int main() {

    strcpy(base64cipher,"6i6Xa7YjTjLDkXDGIHJtqowADpd/Z08=");
    strcpy(base64iv,"rMbY94LVjJ/Ne9LkXHy3qw==");

    len = Base64Decode(iv,base64iv,strlen(base64iv));
    len = Base64Decode(cipher,base64cipher,strlen(base64cipher));

    AES256Decrypt(cleartext,cipher,len);

    return 0;

Anirudh Ramachandran

unread,
Aug 12, 2013, 12:15:13 PM8/12/13
to sjcl-d...@googlegroups.com
Scott,

The SJCL demo page only uses AES-CCM, which is not the same as the CBC mode. If you do want to try CBC, configure SJCL to include cbc and define sjcl.beware before calling sjcl.mode["cbc"]. Example here http://goo.gl/nV8Jnp.

That said, no, I haven't had any further luck interoperating with OpenSSL (using either mode).

Anirudh

Dave

unread,
Apr 14, 2014, 11:58:39 PM4/14/14
to sjcl-d...@googlegroups.com
Hi
Did you ever resolve this issue?
I have some data encoded with SJCL, and I need to decrypt it using OpenSSL. I've tried using CCM mode etc, and found various code samples, but nothing that I try is successful.
Is SJCL compatible with OpenSSL?
Thanks
Dave

Scott Weber

unread,
Apr 15, 2014, 9:48:21 AM4/15/14
to sjcl-d...@googlegroups.com
Sorry Dave,
No I haven't solved this.  We found an alternative method to move the data.

As to "if it's compatible", I don't know.  I'm not an encryption expert.  Just a C++ coder.  Those guys are usually math PhD's.

If it was encrypted using SJCL, maybe can you run it through an SJCL decryption.  Perhaps using NodeJS or similar.

Another possibility might be to try reversing the cypher and/or IV bytes at 32 bit values from little endian to big endian.  I have seen that work on data between C++/OpenSSL and C#.  I was going to try that, but we changed direction before I could pursue it.

Good luck.

-Scott

Nate Rosenblum

unread,
May 1, 2014, 5:41:00 PM5/1/14
to sjcl-d...@googlegroups.com
Sorry Dave,
No I haven't solved this.  We found an alternative method to move the data.

As to "if it's compatible", I don't know.  I'm not an encryption expert.  Just a C++ coder.  Those guys are usually math PhD's.

If it was encrypted using SJCL, maybe can you run it through an SJCL decryption.  Perhaps using NodeJS or similar.

Another possibility might be to try reversing the cypher and/or IV bytes at 32 bit values from little endian to big endian.  I have seen that work on data between C++/OpenSSL and C#.  I was going to try that, but we changed direction before I could pursue it

Hi all,

I came across this discussion while diagnosing a similar-sounding integration problem between OpenSSL and BouncyCastle. The problem for me turned out to be a subtle API difference, and looking at SJCL I suspect the problem is the same there. The problem stems from the way that the two libraries provide the ciphertext and MAC outputs when encrypting. OpenSSL does these through two method calls:

    EVP_EncryptFinal_ex(&ctx, outbuf, &outlen); // <-- returns your ciphertext in outbuf
    EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, macsize, someotherbuf); // <-- returns the MAC in some other buf

On the other hand, BouncyCastle returns a concatenation of ciphertext|mac:

    cipher.doFinal(concatenated, outputLen); // the buffer concatenated contains both results

Looking at the SJCL source I see that its interface is similar. Failure to remove the tag (MAC) from the end of the SJCL encryption result and pass it to OpenSSL decryption via

     EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, macsize, (void*) mac);

will lead to decryption errors. 

Can't say for sure that this was your problem w/o seeing the code, but it seems pretty likely. Certainly confused me for a few hours.

Best,

--nate
Reply all
Reply to author
Forward
0 new messages