I'm playing with various crypto libraries to encrypt/decrypt in
AES-128-CTR.  2 of the 3 libs inter-operate fine with each other; i.e. I
can encrypt with one and decrypt with the other and vice versa.
However, when I use openssl with any of these libs, I am having
problems.  It seems like up to the first 16 bytes is decrypted fine.
But after that, it's messed up.  For example, if I use openssl to
encrypt the string, "12345678901234567890", the other end will only
decrypt "1234567890123456" followed by 4 bytes of garbage.  And if the
other lib encrypts "12345678901234567890", openssl will only decrypt
"1234567890123456" followed by 4 bytes of garbage.  However, if both
ends is openssl, everything seems fine.  But because the other 2 libs
seem to work well with each other, I guess I'm not using the openssl
api's correctly?  Below is the code for my AES-128-CTR
encrypter/decrypter

        class AES128CTR
        {
        protected:
                bool                    m_bEncrypt; // indicates if this
is used to encrypt or decrypt
                AES_KEY         m_key;
                U8                      m_iv[AES_BLOCK_SIZE];
                U8                      m_ecount_buf[AES_BLOCK_SIZE];
                U32                     m_num;

        public:
                AES128CTR(const U8* key, U32 len, const U8* iv, U32
ivlen, bool bEncrypt) : m_bEncrypt(bEncrypt), m_num(0)
                {
                        assert(len >= 16 && ivlen >= 16); // 
                        if (len < 16 || ivlen < 16) return; // key and
iv need to be 128-bits
                        len = ivlen = 16;

                        memcpy(m_iv, iv, ivlen);

                        memset(m_ecount_buf, 0, sizeof(m_ecount_buf));

                        int ret = AES_set_encrypt_key(key,
len*8/*bits*/, &m_key); // returns 0 for success
                        assert(!ret);
                }
                virtual ~AES128CTR()
                {
                }
                bool encrypt(const U8* in, U32 inlen, U8* out, U32*
outlen)
                {
                        if (m_bEncrypt)
                        {
                                AES_ctr128_encrypt(in, out, inlen,
&m_key, m_iv, m_ecount_buf, &m_num);
                                *outlen = inlen;
                                return true;
                        }
                        return false;
                }
                bool decrypt(const U8* in, U32 inlen, U8* out, U32*
outlen)
                {
                        if (!m_bEncrypt)
                        {
                                // NOTE: calling AES_ctr128_encrypt to
decrypt because AES_ctr128_encrypt is its own inverse.
                                AES_ctr128_encrypt(in, out, inlen,
&m_key, m_iv, m_ecount_buf, &m_num);
                                *outlen = inlen;
                                return true;
                        }
                        return false;
                }
        };

....

        // this is how I encrypt data
        AES128CTR aesEncrypt;
        const char* str = "12345678901234567890";
        U8 ciphertext[1024];
        U32 len = sizeof(ciphertext);
        aesEncrypt.encrypt((U8*)str, strlen(str), ciphertext, &len);

...

        // this is how I decrypt data
        AES128CTR aesDecrypt;
        U8 plaintext[1024];
        U32 len = sizeof(plaintext);
        aesDecrypt.decrypt(in, inlen, plaintext, &len); 

Reply via email to