diff --git a/library/ccm.c b/library/ccm.c
new file mode 100644
index 0000000..d39387f
--- /dev/null
+++ b/library/ccm.c
@@ -0,0 +1,463 @@
+/*
+ *  NIST SP800-38C compliant CCM implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+/*
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ */
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "mbedcrypto/config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#if defined(MBEDCRYPTO_CCM_C)
+
+#include "mbedcrypto/ccm.h"
+#include "mbedcrypto/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDCRYPTO_SELF_TEST) && defined(MBEDCRYPTO_AES_C)
+#if defined(MBEDCRYPTO_PLATFORM_C)
+#include "mbedcrypto/platform.h"
+#else
+#include <stdio.h>
+#define mbedcrypto_printf printf
+#endif /* MBEDCRYPTO_PLATFORM_C */
+#endif /* MBEDCRYPTO_SELF_TEST && MBEDCRYPTO_AES_C */
+
+#if !defined(MBEDCRYPTO_CCM_ALT)
+
+#define CCM_ENCRYPT 0
+#define CCM_DECRYPT 1
+
+/*
+ * Initialize context
+ */
+void mbedcrypto_ccm_init( mbedcrypto_ccm_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedcrypto_ccm_context ) );
+}
+
+int mbedcrypto_ccm_setkey( mbedcrypto_ccm_context *ctx,
+                        mbedcrypto_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits )
+{
+    int ret;
+    const mbedcrypto_cipher_info_t *cipher_info;
+
+    cipher_info = mbedcrypto_cipher_info_from_values( cipher, keybits, MBEDCRYPTO_MODE_ECB );
+    if( cipher_info == NULL )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+    if( cipher_info->block_size != 16 )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+    mbedcrypto_cipher_free( &ctx->cipher_ctx );
+
+    if( ( ret = mbedcrypto_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedcrypto_cipher_setkey( &ctx->cipher_ctx, key, keybits,
+                               MBEDCRYPTO_ENCRYPT ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Free context
+ */
+void mbedcrypto_ccm_free( mbedcrypto_ccm_context *ctx )
+{
+    mbedcrypto_cipher_free( &ctx->cipher_ctx );
+    mbedcrypto_platform_zeroize( ctx, sizeof( mbedcrypto_ccm_context ) );
+}
+
+/*
+ * Macros for common operations.
+ * Results in smaller compiled code than static inline functions.
+ */
+
+/*
+ * Update the CBC-MAC state in y using a block in b
+ * (Always using b as the source helps the compiler optimise a bit better.)
+ */
+#define UPDATE_CBC_MAC                                                      \
+    for( i = 0; i < 16; i++ )                                               \
+        y[i] ^= b[i];                                                       \
+                                                                            \
+    if( ( ret = mbedcrypto_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
+        return( ret );
+
+/*
+ * Encrypt or decrypt a partial block with CTR
+ * Warning: using b for temporary storage! src and dst must not be b!
+ * This avoids allocating one more 16 bytes buffer while allowing src == dst.
+ */
+#define CTR_CRYPT( dst, src, len  )                                            \
+    if( ( ret = mbedcrypto_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 )  \
+        return( ret );                                                         \
+                                                                               \
+    for( i = 0; i < len; i++ )                                                 \
+        dst[i] = src[i] ^ b[i];
+
+/*
+ * Authenticated encryption or decryption
+ */
+static int ccm_auth_crypt( mbedcrypto_ccm_context *ctx, int mode, size_t length,
+                           const unsigned char *iv, size_t iv_len,
+                           const unsigned char *add, size_t add_len,
+                           const unsigned char *input, unsigned char *output,
+                           unsigned char *tag, size_t tag_len )
+{
+    int ret;
+    unsigned char i;
+    unsigned char q;
+    size_t len_left, olen;
+    unsigned char b[16];
+    unsigned char y[16];
+    unsigned char ctr[16];
+    const unsigned char *src;
+    unsigned char *dst;
+
+    /*
+     * Check length requirements: SP800-38C A.1
+     * Additional requirement: a < 2^16 - 2^8 to simplify the code.
+     * 'length' checked later (when writing it to the first block)
+     */
+    if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+    /* Also implies q is within bounds */
+    if( iv_len < 7 || iv_len > 13 )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+    if( add_len > 0xFF00 )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+    q = 16 - 1 - (unsigned char) iv_len;
+
+    /*
+     * First block B_0:
+     * 0        .. 0        flags
+     * 1        .. iv_len   nonce (aka iv)
+     * iv_len+1 .. 15       length
+     *
+     * With flags as (bits):
+     * 7        0
+     * 6        add present?
+     * 5 .. 3   (t - 2) / 2
+     * 2 .. 0   q - 1
+     */
+    b[0] = 0;
+    b[0] |= ( add_len > 0 ) << 6;
+    b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
+    b[0] |= q - 1;
+
+    memcpy( b + 1, iv, iv_len );
+
+    for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
+        b[15-i] = (unsigned char)( len_left & 0xFF );
+
+    if( len_left > 0 )
+        return( MBEDCRYPTO_ERR_CCM_BAD_INPUT );
+
+
+    /* Start CBC-MAC with first block */
+    memset( y, 0, 16 );
+    UPDATE_CBC_MAC;
+
+    /*
+     * If there is additional data, update CBC-MAC with
+     * add_len, add, 0 (padding to a block boundary)
+     */
+    if( add_len > 0 )
+    {
+        size_t use_len;
+        len_left = add_len;
+        src = add;
+
+        memset( b, 0, 16 );
+        b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
+        b[1] = (unsigned char)( ( add_len      ) & 0xFF );
+
+        use_len = len_left < 16 - 2 ? len_left : 16 - 2;
+        memcpy( b + 2, src, use_len );
+        len_left -= use_len;
+        src += use_len;
+
+        UPDATE_CBC_MAC;
+
+        while( len_left > 0 )
+        {
+            use_len = len_left > 16 ? 16 : len_left;
+
+            memset( b, 0, 16 );
+            memcpy( b, src, use_len );
+            UPDATE_CBC_MAC;
+
+            len_left -= use_len;
+            src += use_len;
+        }
+    }
+
+    /*
+     * Prepare counter block for encryption:
+     * 0        .. 0        flags
+     * 1        .. iv_len   nonce (aka iv)
+     * iv_len+1 .. 15       counter (initially 1)
+     *
+     * With flags as (bits):
+     * 7 .. 3   0
+     * 2 .. 0   q - 1
+     */
+    ctr[0] = q - 1;
+    memcpy( ctr + 1, iv, iv_len );
+    memset( ctr + 1 + iv_len, 0, q );
+    ctr[15] = 1;
+
+    /*
+     * Authenticate and {en,de}crypt the message.
+     *
+     * The only difference between encryption and decryption is
+     * the respective order of authentication and {en,de}cryption.
+     */
+    len_left = length;
+    src = input;
+    dst = output;
+
+    while( len_left > 0 )
+    {
+        size_t use_len = len_left > 16 ? 16 : len_left;
+
+        if( mode == CCM_ENCRYPT )
+        {
+            memset( b, 0, 16 );
+            memcpy( b, src, use_len );
+            UPDATE_CBC_MAC;
+        }
+
+        CTR_CRYPT( dst, src, use_len );
+
+        if( mode == CCM_DECRYPT )
+        {
+            memset( b, 0, 16 );
+            memcpy( b, dst, use_len );
+            UPDATE_CBC_MAC;
+        }
+
+        dst += use_len;
+        src += use_len;
+        len_left -= use_len;
+
+        /*
+         * Increment counter.
+         * No need to check for overflow thanks to the length check above.
+         */
+        for( i = 0; i < q; i++ )
+            if( ++ctr[15-i] != 0 )
+                break;
+    }
+
+    /*
+     * Authentication: reset counter and crypt/mask internal tag
+     */
+    for( i = 0; i < q; i++ )
+        ctr[15-i] = 0;
+
+    CTR_CRYPT( y, y, 16 );
+    memcpy( tag, y, tag_len );
+
+    return( 0 );
+}
+
+/*
+ * Authenticated encryption
+ */
+int mbedcrypto_ccm_encrypt_and_tag( mbedcrypto_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len )
+{
+    return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
+                            add, add_len, input, output, tag, tag_len ) );
+}
+
+/*
+ * Authenticated decryption
+ */
+int mbedcrypto_ccm_auth_decrypt( mbedcrypto_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len )
+{
+    int ret;
+    unsigned char check_tag[16];
+    unsigned char i;
+    int diff;
+
+    if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
+                                iv, iv_len, add, add_len,
+                                input, output, check_tag, tag_len ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedcrypto_platform_zeroize( output, length );
+        return( MBEDCRYPTO_ERR_CCM_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+#endif /* !MBEDCRYPTO_CCM_ALT */
+
+#if defined(MBEDCRYPTO_SELF_TEST) && defined(MBEDCRYPTO_AES_C)
+/*
+ * Examples 1 to 3 from SP800-38C Appendix C
+ */
+
+#define NB_TESTS 3
+
+/*
+ * The data is the same for all tests, only the used length changes
+ */
+static const unsigned char key[] = {
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
+};
+
+static const unsigned char iv[] = {
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b
+};
+
+static const unsigned char ad[] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13
+};
+
+static const unsigned char msg[] = {
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+};
+
+static const size_t iv_len [NB_TESTS] = { 7, 8,  12 };
+static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
+static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
+static const size_t tag_len[NB_TESTS] = { 4, 6,  8  };
+
+static const unsigned char res[NB_TESTS][32] = {
+    {   0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
+    {   0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
+        0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
+        0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
+    {   0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
+        0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
+        0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
+        0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
+};
+
+int mbedcrypto_ccm_self_test( int verbose )
+{
+    mbedcrypto_ccm_context ctx;
+    unsigned char out[32];
+    size_t i;
+    int ret;
+
+    mbedcrypto_ccm_init( &ctx );
+
+    if( mbedcrypto_ccm_setkey( &ctx, MBEDCRYPTO_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "  CCM: setup failed" );
+
+        return( 1 );
+    }
+
+    for( i = 0; i < NB_TESTS; i++ )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "  CCM-AES #%u: ", (unsigned int) i + 1 );
+
+        ret = mbedcrypto_ccm_encrypt_and_tag( &ctx, msg_len[i],
+                                   iv, iv_len[i], ad, add_len[i],
+                                   msg, out,
+                                   out + msg_len[i], tag_len[i] );
+
+        if( ret != 0 ||
+            memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedcrypto_printf( "failed\n" );
+
+            return( 1 );
+        }
+
+        ret = mbedcrypto_ccm_auth_decrypt( &ctx, msg_len[i],
+                                iv, iv_len[i], ad, add_len[i],
+                                res[i], out,
+                                res[i] + msg_len[i], tag_len[i] );
+
+        if( ret != 0 ||
+            memcmp( out, msg, msg_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedcrypto_printf( "failed\n" );
+
+            return( 1 );
+        }
+
+        if( verbose != 0 )
+            mbedcrypto_printf( "passed\n" );
+    }
+
+    mbedcrypto_ccm_free( &ctx );
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDCRYPTO_SELF_TEST && MBEDCRYPTO_AES_C */
+
+#endif /* MBEDCRYPTO_CCM_C */
