Fix chunked ccm update.

Signed-off-by: Mateusz Starzyk <mateusz.starzyk@mobica.com>
diff --git a/library/ccm.c b/library/ccm.c
index 4f7ebfa..5450e40 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -373,42 +373,49 @@
         ctx->processed += use_len;
         memcpy( ctx->b + offset, input, use_len );
 
+        if( ctx->mode == MBEDTLS_CCM_ENCRYPT || \
+            ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT )
+        {
+            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
+            {
+                UPDATE_CBC_MAC;
+            }
+            ret = mbedtls_ccm_crypt( ctx, offset, use_len, ctx->b + offset, output );
+            if( ret != 0 )
+                return ret;
+        }
+
+        if( ctx->mode == MBEDTLS_CCM_DECRYPT || \
+            ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
+        {
+            ret = mbedtls_ccm_crypt( ctx, offset, use_len, ctx->b + offset, output );
+            if( ret != 0 )
+                return ret;
+
+            for( i = 0; i < use_len; i++ )
+                ctx->y[i + offset] ^= output[i];
+
+            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
+            {
+                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
+                {
+                    ctx->state |= CCM_STATE__ERROR;
+                    return( ret );
+                }
+            }
+        }
+
         if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
         {
-            if( ctx->mode == MBEDTLS_CCM_ENCRYPT || \
-                ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT )
-            {
-                UPDATE_CBC_MAC;
-                ret = mbedtls_ccm_crypt( ctx, 0, use_len, ctx->b, output );
-                if( ret != 0 )
-                    return ret;
-                memset( ctx->b, 0, 16 );
-            }
-
-            if( ctx->mode == MBEDTLS_CCM_DECRYPT || \
-                ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
-            {
-                ret = mbedtls_ccm_crypt( ctx, 0, use_len, ctx->b, output );
-                if( ret != 0 )
-                    return ret;
-                memset( ctx->b, 0, 16 );
-                memcpy( ctx->b, output, use_len );
-                UPDATE_CBC_MAC;
-                memset( ctx->b, 0, 16 );
-            }
-
-            input_len -= use_len;
-            input += use_len;
-            output += use_len;
-
-            /*
-            * Increment counter.
-            * No need to check for overflow thanks to the length check above.
-            */
             for( i = 0; i < ctx->q; i++ )
-                if( ++(ctx->ctr)[15-i] != 0 )
-                    break;
+            if( ++(ctx->ctr)[15-i] != 0 )
+                break;
+            memset( ctx->b, 0, 16 );
         }
+
+        input_len -= use_len;
+        input += use_len;
+        output += use_len;
     }
 
     return 0;