Merge pull request #5131 from gilles-peskine-arm/dlopen-test

dlopen test
diff --git a/.gitignore b/.gitignore
index 0792920..26986d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,9 @@
 # Generated documentation:
 /apidoc
 
+# PSA Crypto compliance test repo, cloned by test_psa_compliance.py
+/psa-arch-tests
+
 # Editor navigation files:
 /GPATH
 /GRTAGS
diff --git a/BRANCHES.md b/BRANCHES.md
index a63f070..60218b0 100644
--- a/BRANCHES.md
+++ b/BRANCHES.md
@@ -62,7 +62,7 @@
 increase code size for a security fix.)
 
 For contributors, see the [Backwards Compatibility section of
-CONTRIBUTING](CONTRIBUTING.md#cackwords-compatibility).
+CONTRIBUTING](CONTRIBUTING.md#backwards-compatibility).
 
 ## Current Branches
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b3a9547..dcaa360 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -52,8 +52,7 @@
 The list of maintained branches can be found in the [Current Branches section
 of BRANCHES.md](BRANCHES.md#current-branches).
 
-Currently maintained LTS branches are:
-1. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
+The only currently maintained LTS branch is:
 1. [mbedtls-2.16](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.16)
 
 
diff --git a/ChangeLog.d/bugfix-for-gcm-long-iv-size.txt b/ChangeLog.d/bugfix-for-gcm-long-iv-size.txt
new file mode 100644
index 0000000..c04c4aa
--- /dev/null
+++ b/ChangeLog.d/bugfix-for-gcm-long-iv-size.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix a bug in mbedtls_gcm_starts() when bits of iv are longer than 2^32.
+   * Fix #4884.
+
diff --git a/ChangeLog.d/ccm_star_no_tag.txt b/ChangeLog.d/ccm_star_no_tag.txt
new file mode 100644
index 0000000..dbd25d1
--- /dev/null
+++ b/ChangeLog.d/ccm_star_no_tag.txt
@@ -0,0 +1,10 @@
+Changes
+   * Ignore plaintext/ciphertext lengths for CCM*-no-tag operations.
+     For CCM* encryption/decryption without authentication, input
+     length will be ignored.
+
+Features
+   * Add support for CCM*-no-tag cipher to the PSA.
+     Currently only 13-byte long IV's are supported.
+     For decryption a minimum of 16-byte long input is expected.
+     These restrictions may be subject to change.
diff --git a/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt b/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt
new file mode 100644
index 0000000..ca3f9ac
--- /dev/null
+++ b/ChangeLog.d/chacha20-poly1305-invalid-nonce.txt
@@ -0,0 +1,3 @@
+Changes
+   * Indicate in the error returned if the nonce length used with
+     ChaCha20-Poly1305 is invalid, and not just unsupported.
diff --git a/ChangeLog.d/constant_time_module.txt b/ChangeLog.d/constant_time_module.txt
new file mode 100644
index 0000000..ebb0b7f
--- /dev/null
+++ b/ChangeLog.d/constant_time_module.txt
@@ -0,0 +1,10 @@
+Changes
+    * The mbedcrypto library includes a new source code module constant_time.c,
+      containing various functions meant to resist timing side channel attacks.
+      This module does not have a separate configuration option, and functions
+      from this module will be included in the build as required. Currently
+      most of the interface of this module is private and may change at any
+      time.
+
+Features
+    * Add new API mbedtls_ct_memcmp for constant time buffer comparison.
diff --git a/ChangeLog.d/fix_compilation_ssl_tests.txt b/ChangeLog.d/fix_compilation_ssl_tests.txt
new file mode 100644
index 0000000..202e5c4
--- /dev/null
+++ b/ChangeLog.d/fix_compilation_ssl_tests.txt
@@ -0,0 +1,3 @@
+Bugfix
+   * Fix an uninitialized variable warning in test_suite_ssl.function with GCC
+     version 11.
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 70c5ff4..fdbf0e9 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -76,7 +76,7 @@
 {
     psa_status_t status;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Import an AES key...\t");
     fflush(stdout);
@@ -95,7 +95,7 @@
     psa_set_key_bits(&attributes, 128);
 
     /* Import the key */
-    status = psa_import_key(&attributes, key, key_len, &key);
+    status = psa_import_key(&attributes, key, key_len, &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to import key\n");
         return;
@@ -106,7 +106,7 @@
     psa_reset_key_attributes(&attributes);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 }
@@ -135,7 +135,7 @@
                         0xa9, 0xe8, 0xcc, 0xac, 0xd0, 0xf6, 0x54, 0x5c};
     uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = {0};
     size_t signature_length;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Sign a message...\t");
     fflush(stdout);
@@ -154,14 +154,14 @@
     psa_set_key_bits(&attributes, 1024);
 
     /* Import the key */
-    status = psa_import_key(&attributes, key, key_len, &key);
+    status = psa_import_key(&attributes, key, key_len, &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to import key\n");
         return;
     }
 
     /* Sign message using the key */
-    status = psa_sign_hash(key, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
+    status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
                            hash, sizeof(hash),
                            signature, sizeof(signature),
                            &signature_length);
@@ -176,7 +176,7 @@
     psa_reset_key_attributes(&attributes);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 }
@@ -213,7 +213,7 @@
     size_t iv_len;
     uint8_t output[block_size];
     size_t output_len;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
 
     printf("Encrypt with cipher...\t");
@@ -232,7 +232,7 @@
     psa_set_key_algorithm(&attributes, alg);
     psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
     psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, key_len, &key);
+    status = psa_import_key(&attributes, key, key_len, &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to import a key\n");
         return;
@@ -240,7 +240,7 @@
     psa_reset_key_attributes(&attributes);
 
     /* Encrypt the plaintext */
-    status = psa_cipher_encrypt_setup(&operation, key, alg);
+    status = psa_cipher_encrypt_setup(&operation, key_id, alg);
     if (status != PSA_SUCCESS) {
         printf("Failed to begin cipher operation\n");
         return;
@@ -268,7 +268,7 @@
     psa_cipher_abort(&operation);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 }
@@ -298,7 +298,7 @@
     uint8_t iv[block_size] = ENCRYPTED_WITH_IV;
     uint8_t output[block_size];
     size_t output_len;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Decrypt with cipher...\t");
     fflush(stdout);
@@ -316,7 +316,7 @@
     psa_set_key_algorithm(&attributes, alg);
     psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
     psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, key_len, &key);
+    status = psa_import_key(&attributes, key, key_len, &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to import a key\n");
         return;
@@ -324,7 +324,7 @@
     psa_reset_key_attributes(&attributes);
 
     /* Decrypt the ciphertext */
-    status = psa_cipher_decrypt_setup(&operation, key, alg);
+    status = psa_cipher_decrypt_setup(&operation, key_id, alg);
     if (status != PSA_SUCCESS) {
         printf("Failed to begin cipher operation\n");
         return;
@@ -352,7 +352,7 @@
     psa_cipher_abort(&operation);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 }
@@ -702,7 +702,7 @@
     size_t output_length = 0;
     size_t tag_length = 16;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Authenticate encrypt...\t");
     fflush(stdout);
@@ -726,11 +726,11 @@
     psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
     psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
     psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key, sizeof(key), &key);
+    status = psa_import_key(&attributes, key, sizeof(key), &key_id);
     psa_reset_key_attributes(&attributes);
 
     /* Authenticate and encrypt */
-    status = psa_aead_encrypt(key, PSA_ALG_CCM,
+    status = psa_aead_encrypt(key_id, PSA_ALG_CCM,
                               nonce, sizeof(nonce),
                               additional_data, sizeof(additional_data),
                               input_data, sizeof(input_data),
@@ -747,7 +747,7 @@
     free(output_data);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 ```
@@ -773,7 +773,7 @@
     size_t output_size = 0;
     size_t output_length = 0;
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Authenticate decrypt...\t");
     fflush(stdout);
@@ -797,7 +797,7 @@
     psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
     psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
     psa_set_key_bits(&attributes, 128);
-    status = psa_import_key(&attributes, key_data, sizeof(key_data), &key);
+    status = psa_import_key(&attributes, key_data, sizeof(key_data), &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to import a key\n");
         return;
@@ -805,7 +805,7 @@
     psa_reset_key_attributes(&attributes);
 
     /* Authenticate and decrypt */
-    status = psa_aead_decrypt(key, PSA_ALG_CCM,
+    status = psa_aead_decrypt(key_id, PSA_ALG_CCM,
                               nonce, sizeof(nonce),
                               additional_data, sizeof(additional_data),
                               input_data, sizeof(input_data),
@@ -822,7 +822,7 @@
     free(output_data);
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 ```
@@ -848,7 +848,7 @@
     size_t exported_length = 0;
     static uint8_t exported[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits)];
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    psa_key_id_t key;
+    psa_key_id_t key_id;
 
     printf("Generate a key pair...\t");
     fflush(stdout);
@@ -867,14 +867,14 @@
     psa_set_key_type(&attributes,
                      PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
     psa_set_key_bits(&attributes, key_bits);
-    status = psa_generate_key(&attributes, &key);
+    status = psa_generate_key(&attributes, &key_id);
     if (status != PSA_SUCCESS) {
         printf("Failed to generate key\n");
         return;
     }
     psa_reset_key_attributes(&attributes);
 
-    status = psa_export_public_key(key, exported, sizeof(exported),
+    status = psa_export_public_key(key_id, exported, sizeof(exported),
                                    &exported_length);
     if (status != PSA_SUCCESS) {
         printf("Failed to export public key %ld\n", status);
@@ -884,7 +884,7 @@
     printf("Exported a public key\n");
 
     /* Destroy the key */
-    psa_destroy_key(key);
+    psa_destroy_key(key_id);
 
     mbedtls_psa_crypto_free();
 ```
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index becbfae..e381c11 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -511,10 +511,6 @@
  * \brief      This function performs an AES-CTR encryption or decryption
  *             operation.
  *
- *             This function performs the operation defined in the \p mode
- *             parameter (encrypt/decrypt), on the input data buffer
- *             defined in the \p input parameter.
- *
  *             Due to the nature of CTR, you must use the same key schedule
  *             for both encryption and decryption operations. Therefore, you
  *             must use the context initialized with mbedtls_aes_setkey_enc()
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 6f991fe..1be1689 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -198,6 +198,7 @@
  * \param ctx       The CCM context to use for encryption. This must be
  *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
+ *                  For tag length = 0, input length is ignored.
  * \param iv        The initialization vector (nonce). This must be a readable
  *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
@@ -279,6 +280,7 @@
  * \param ctx       The CCM context to use for decryption. This must be
  *                  initialized and bound to a key.
  * \param length    The length of the input data in Bytes.
+ *                  For tag length = 0, input length is ignored.
  * \param iv        The initialization vector (nonce). This must be a readable
  *                  buffer of at least \p iv_len Bytes.
  * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index b4630f6..892771e 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -140,9 +140,15 @@
     MBEDTLS_CIPHER_AES_128_CCM,          /**< AES cipher with 128-bit CCM mode. */
     MBEDTLS_CIPHER_AES_192_CCM,          /**< AES cipher with 192-bit CCM mode. */
     MBEDTLS_CIPHER_AES_256_CCM,          /**< AES cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, /**< AES cipher with 128-bit CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, /**< AES cipher with 192-bit CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, /**< AES cipher with 256-bit CCM_STAR_NO_TAG mode. */
     MBEDTLS_CIPHER_CAMELLIA_128_CCM,     /**< Camellia cipher with 128-bit CCM mode. */
     MBEDTLS_CIPHER_CAMELLIA_192_CCM,     /**< Camellia cipher with 192-bit CCM mode. */
     MBEDTLS_CIPHER_CAMELLIA_256_CCM,     /**< Camellia cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, /**< Camellia cipher with 128-bit CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, /**< Camellia cipher with 192-bit CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, /**< Camellia cipher with 256-bit CCM_STAR_NO_TAG mode. */
     MBEDTLS_CIPHER_ARIA_128_ECB,         /**< Aria cipher with 128-bit key and ECB mode. */
     MBEDTLS_CIPHER_ARIA_192_ECB,         /**< Aria cipher with 192-bit key and ECB mode. */
     MBEDTLS_CIPHER_ARIA_256_ECB,         /**< Aria cipher with 256-bit key and ECB mode. */
@@ -161,6 +167,9 @@
     MBEDTLS_CIPHER_ARIA_128_CCM,         /**< Aria cipher with 128-bit key and CCM mode. */
     MBEDTLS_CIPHER_ARIA_192_CCM,         /**< Aria cipher with 192-bit key and CCM mode. */
     MBEDTLS_CIPHER_ARIA_256_CCM,         /**< Aria cipher with 256-bit key and CCM mode. */
+    MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, /**< Aria cipher with 128-bit key and CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, /**< Aria cipher with 192-bit key and CCM_STAR_NO_TAG mode. */
+    MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, /**< Aria cipher with 256-bit key and CCM_STAR_NO_TAG mode. */
     MBEDTLS_CIPHER_AES_128_OFB,          /**< AES 128-bit cipher in OFB mode. */
     MBEDTLS_CIPHER_AES_192_OFB,          /**< AES 192-bit cipher in OFB mode. */
     MBEDTLS_CIPHER_AES_256_OFB,          /**< AES 256-bit cipher in OFB mode. */
@@ -187,6 +196,7 @@
     MBEDTLS_MODE_GCM,                    /**< The GCM cipher mode.         */
     MBEDTLS_MODE_STREAM,                 /**< The stream cipher mode.      */
     MBEDTLS_MODE_CCM,                    /**< The CCM cipher mode.         */
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,        /**< The CCM*-no-tag cipher mode. */
     MBEDTLS_MODE_XTS,                    /**< The XTS cipher mode.         */
     MBEDTLS_MODE_CHACHAPOLY,             /**< The ChaCha-Poly cipher mode. */
     MBEDTLS_MODE_KW,                     /**< The SP800-38F KW mode */
diff --git a/include/mbedtls/constant_time.h b/include/mbedtls/constant_time.h
new file mode 100644
index 0000000..c5de57a
--- /dev/null
+++ b/include/mbedtls/constant_time.h
@@ -0,0 +1,45 @@
+/**
+ *  Constant-time functions
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  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.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_H
+#define MBEDTLS_CONSTANT_TIME_H
+
+#include <stddef.h>
+
+
+/** Constant-time buffer comparison without branches.
+ *
+ * This is equivalent to the standard memcmp function, but is likely to be
+ * compiled to code using bitwise operation rather than a branch.
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param a     Pointer to the first buffer.
+ * \param b     Pointer to the second buffer.
+ * \param n     The number of bytes to compare in the buffer.
+ *
+ * \return      Zero if the content of the two buffer is the same,
+ *              otherwise non-zero.
+ */
+int mbedtls_ct_memcmp( const void *a,
+                       const void *b,
+                       size_t n );
+
+#endif /* MBEDTLS_CONSTANT_TIME_H */
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 80bcd72..c54c035 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -51,6 +51,9 @@
         case MBEDTLS_CIPHER_AES_128_CCM:
         case MBEDTLS_CIPHER_AES_192_CCM:
         case MBEDTLS_CIPHER_AES_256_CCM:
+        case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:
+        case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:
+        case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:
         case MBEDTLS_CIPHER_AES_128_GCM:
         case MBEDTLS_CIPHER_AES_192_GCM:
         case MBEDTLS_CIPHER_AES_256_GCM:
@@ -66,6 +69,9 @@
         /* case MBEDTLS_CIPHER_ARIA_128_CCM:
            case MBEDTLS_CIPHER_ARIA_192_CCM:
            case MBEDTLS_CIPHER_ARIA_256_CCM:
+           case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:
+           case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:
+           case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:
            case MBEDTLS_CIPHER_ARIA_128_GCM:
            case MBEDTLS_CIPHER_ARIA_192_GCM:
            case MBEDTLS_CIPHER_ARIA_256_GCM:
@@ -90,6 +96,8 @@
             return( PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, taglen ) );
         case MBEDTLS_MODE_CCM:
             return( PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, taglen ) );
+        case MBEDTLS_MODE_CCM_STAR_NO_TAG:
+            return PSA_ALG_CCM_STAR_NO_TAG;
         case MBEDTLS_MODE_CBC:
             if( taglen == 0 )
                 return( PSA_ALG_CBC_NO_PADDING );
diff --git a/include/mbedtls/sha256.h b/include/mbedtls/sha256.h
index 9e6f59d..0cbbac1 100644
--- a/include/mbedtls/sha256.h
+++ b/include/mbedtls/sha256.h
@@ -167,6 +167,9 @@
  *                 for SHA-256, \c 28 bytes for SHA-224.
  * \param is224    Determines which function to use. This must be
  *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
  */
 int mbedtls_sha256( const unsigned char *input,
                     size_t ilen,
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 5d04a11..45e0544 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -605,6 +605,8 @@
 
 #define MBEDTLS_PREMASTER_SIZE     sizeof( union mbedtls_ssl_premaster_secret )
 
+#define MBEDTLS_TLS1_3_MD_MAX_SIZE         MBEDTLS_MD_MAX_SIZE
+
 /* Length in number of bytes of the TLS sequence number */
 #define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
 
@@ -1050,6 +1052,14 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED &&
           !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 
+typedef struct
+{
+    unsigned char client_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
+    unsigned char server_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
+    unsigned char exporter_master_secret             [ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
+    unsigned char resumption_master_secret           [ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
+} mbedtls_ssl_tls1_3_application_secrets;
+
 #if defined(MBEDTLS_SSL_DTLS_SRTP)
 
 #define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH             255
@@ -1140,6 +1150,10 @@
 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
     int MBEDTLS_PRIVATE(encrypt_then_mac);       /*!< flag for EtM activation                */
 #endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    mbedtls_ssl_tls1_3_application_secrets MBEDTLS_PRIVATE(app_secrets);
+#endif
 };
 
 /*
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 5f230e0..af8a4a6 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -991,7 +991,8 @@
          (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
      (key_type) == PSA_KEY_TYPE_CHACHA20 && \
          (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \
-     0)
+         (alg) == PSA_ALG_CCM_STAR_NO_TAG ? 13 : \
+         0)
 
 /** The maximum IV size for all supported cipher algorithms, in bytes.
  *
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index f0d76fb..5a903f8 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -1202,6 +1202,17 @@
  */
 #define PSA_ALG_CCM                             ((psa_algorithm_t)0x05500100)
 
+/** The CCM* cipher mode without authentication.
+ *
+ * This is CCM* as specified in IEEE 802.15.4 §7, with a tag length of 0.
+ * For CCM* with a nonzero tag length, use the AEAD algorithm #PSA_ALG_CCM.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * Currently only 13-byte long IV's are supported.
+ */
+#define PSA_ALG_CCM_STAR_NO_TAG                 ((psa_algorithm_t)0x04c01300)
+
 /** The GCM authenticated encryption algorithm.
  *
  * The underlying block cipher is determined by the key type.
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 18aff5a..caac2d5 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -24,6 +24,7 @@
     chachapoly.c
     cipher.c
     cipher_wrap.c
+    constant_time.c
     cmac.c
     ctr_drbg.c
     des.c
diff --git a/library/Makefile b/library/Makefile
index 01e85cf..bd116be 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -84,6 +84,7 @@
 	     cipher.o \
 	     cipher_wrap.o \
 	     cmac.o \
+	     constant_time.o \
 	     ctr_drbg.o \
 	     des.o \
 	     dhm.o \
@@ -186,6 +187,14 @@
 
 shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
 
+# Windows builds under Mingw can fail if make tries to create archives in the same
+# directory at the same time - see https://bugs.launchpad.net/gcc-arm-embedded/+bug/1848002.
+# This forces builds of the .a files to be serialised.
+ifdef WINDOWS
+libmbedtls.a: | libmbedx509.a
+libmbedx509.a: | libmbedcrypto.a
+endif
+
 # tls
 libmbedtls.a: $(OBJS_TLS)
 	echo "  AR    $@"
diff --git a/library/bignum.c b/library/bignum.c
index 42ec7ac..fdf8c9a 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -41,6 +41,7 @@
 #include "bn_mul.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "constant_time_internal.h"
 
 #include <string.h>
 
@@ -268,162 +269,6 @@
     memcpy(  Y, &T, sizeof( mbedtls_mpi ) );
 }
 
-/**
- * Select between two sign values in constant-time.
- *
- * This is functionally equivalent to second ? a : b but uses only bit
- * operations in order to avoid branches.
- *
- * \param[in] a         The first sign; must be either +1 or -1.
- * \param[in] b         The second sign; must be either +1 or -1.
- * \param[in] second    Must be either 1 (return b) or 0 (return a).
- *
- * \return The selected sign value.
- */
-static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
-{
-    /* In order to avoid questions about what we can reasonnably assume about
-     * the representations of signed integers, move everything to unsigned
-     * by taking advantage of the fact that a and b are either +1 or -1. */
-    unsigned ua = a + 1;
-    unsigned ub = b + 1;
-
-    /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
-    const unsigned mask = second << 1;
-
-    /* select ua or ub */
-    unsigned ur = ( ua & ~mask ) | ( ub & mask );
-
-    /* ur is now 0 or 2, convert back to -1 or +1 */
-    return( (int) ur - 1 );
-}
-
-/*
- * Conditionally assign dest = src, without leaking information
- * about whether the assignment was made or not.
- * dest and src must be arrays of limbs of size n.
- * assign must be 0 or 1.
- */
-static void mpi_safe_cond_assign( size_t n,
-                                  mbedtls_mpi_uint *dest,
-                                  const mbedtls_mpi_uint *src,
-                                  unsigned char assign )
-{
-    size_t i;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
-    const mbedtls_mpi_uint mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    for( i = 0; i < n; i++ )
-        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
-}
-
-/*
- * Conditionally assign X = Y, without leaking information
- * about whether the assignment was made or not.
- * (Leaking information about the respective sizes of X and Y is ok however.)
- */
-int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
-{
-    int ret = 0;
-    size_t i;
-    mbedtls_mpi_uint limb_mask;
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* make sure assign is 0 or 1 in a time-constant manner */
-    assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
-    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
-    limb_mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-
-    X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
-
-    mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
-
-    for( i = Y->n; i < X->n; i++ )
-        X->p[i] &= ~limb_mask;
-
-cleanup:
-    return( ret );
-}
-
-/*
- * Conditionally swap X and Y, without leaking information
- * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
- * different memory access patterns when X and Y are used afterwards.
- */
-int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
-{
-    int ret, s;
-    size_t i;
-    mbedtls_mpi_uint limb_mask;
-    mbedtls_mpi_uint tmp;
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-
-    if( X == Y )
-        return( 0 );
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* make sure swap is 0 or 1 in a time-constant manner */
-    swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
-    /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
-    limb_mask = -swap;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
-
-    s = X->s;
-    X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
-    Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
-
-
-    for( i = 0; i < X->n; i++ )
-    {
-        tmp = X->p[i];
-        X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
-        Y->p[i] = ( Y->p[i] & ~limb_mask ) | (     tmp & limb_mask );
-    }
-
-cleanup:
-    return( ret );
-}
-
 /*
  * Set value from integer
  */
@@ -1246,107 +1091,6 @@
     return( 0 );
 }
 
-/** Decide if an integer is less than the other, without branches.
- *
- * \param x         First integer.
- * \param y         Second integer.
- *
- * \return          1 if \p x is less than \p y, 0 otherwise
- */
-static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
-        const mbedtls_mpi_uint y )
-{
-    mbedtls_mpi_uint ret;
-    mbedtls_mpi_uint cond;
-
-    /*
-     * Check if the most significant bits (MSB) of the operands are different.
-     */
-    cond = ( x ^ y );
-    /*
-     * If the MSB are the same then the difference x-y will be negative (and
-     * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
-     */
-    ret = ( x - y ) & ~cond;
-    /*
-     * If the MSB are different, then the operand with the MSB of 1 is the
-     * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
-     * the MSB of y is 0.)
-     */
-    ret |= y & cond;
-
-
-    ret = ret >> ( biL - 1 );
-
-    return (unsigned) ret;
-}
-
-/*
- * Compare signed values in constant time
- */
-int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
-        unsigned *ret )
-{
-    size_t i;
-    /* The value of any of these variables is either 0 or 1 at all times. */
-    unsigned cond, done, X_is_negative, Y_is_negative;
-
-    MPI_VALIDATE_RET( X != NULL );
-    MPI_VALIDATE_RET( Y != NULL );
-    MPI_VALIDATE_RET( ret != NULL );
-
-    if( X->n != Y->n )
-        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
-
-    /*
-     * Set sign_N to 1 if N >= 0, 0 if N < 0.
-     * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
-     */
-    X_is_negative = ( X->s & 2 ) >> 1;
-    Y_is_negative = ( Y->s & 2 ) >> 1;
-
-    /*
-     * If the signs are different, then the positive operand is the bigger.
-     * That is if X is negative (X_is_negative == 1), then X < Y is true and it
-     * is false if X is positive (X_is_negative == 0).
-     */
-    cond = ( X_is_negative ^ Y_is_negative );
-    *ret = cond & X_is_negative;
-
-    /*
-     * This is a constant-time function. We might have the result, but we still
-     * need to go through the loop. Record if we have the result already.
-     */
-    done = cond;
-
-    for( i = X->n; i > 0; i-- )
-    {
-        /*
-         * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
-         * X and Y are negative.
-         *
-         * Again even if we can make a decision, we just mark the result and
-         * the fact that we are done and continue looping.
-         */
-        cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
-        *ret |= cond & ( 1 - done ) & X_is_negative;
-        done |= cond;
-
-        /*
-         * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
-         * X and Y are positive.
-         *
-         * Again even if we can make a decision, we just mark the result and
-         * the fact that we are done and continue looping.
-         */
-        cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
-        *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
-        done |= cond;
-    }
-
-    return( 0 );
-}
-
 /*
  * Compare signed values
  */
@@ -2207,7 +1951,7 @@
      * so d[n] == 1 and we want to set A to the result of the subtraction
      * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
      * This exactly corresponds to a conditional assignment. */
-    mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
+    mbedtls_ct_mpi_uint_cond_assign( n, A->p, d, (unsigned char) d[n] );
 }
 
 /*
@@ -2227,42 +1971,6 @@
     mpi_montmul( A, &U, N, mm, T );
 }
 
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
-{
-    /* diff = 0 if x == y, non-zero otherwise */
-    const size_t diff = x ^ y;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* diff_msb's most significant bit is equal to x != y */
-    const size_t diff_msb = ( diff | (size_t) -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* diff1 = (x != y) ? 1 : 0 */
-    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
-    return( 1 ^ diff1 );
-}
-
 /**
  * Select an MPI from a table without leaking the index.
  *
@@ -2285,7 +1993,7 @@
     for( size_t i = 0; i < T_size; i++ )
     {
         MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
-                        (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+                        (unsigned char) mbedtls_ct_size_bool_eq( i, idx ) ) );
     }
 
 cleanup:
diff --git a/library/ccm.c b/library/ccm.c
index 15efff7..e062678 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -150,9 +150,20 @@
     if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGHTS_SET) )
         return 0;
 
-    if( ctx->tag_len == 0 && \
-        ( ctx->mode == MBEDTLS_CCM_ENCRYPT || ctx->mode == MBEDTLS_CCM_DECRYPT ) )
-        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+    /* CCM expects non-empty tag.
+     * CCM* allows empty tag. For CCM* without tag, ignore plaintext length.
+     */
+    if( ctx->tag_len == 0 )
+    {
+        if( ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT || ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
+        {
+            ctx->plaintext_len = 0;
+        }
+        else
+        {
+            return( MBEDTLS_ERR_CCM_BAD_INPUT );
+        }
+    }
 
     /*
      * First block:
@@ -342,7 +353,10 @@
         return MBEDTLS_ERR_CCM_BAD_INPUT;
     }
 
-    if( ctx->processed + input_len > ctx->plaintext_len )
+    /* Check against plaintext length only if performing operation with
+     * authentication
+     */
+    if( ctx->tag_len != 0 && ctx->processed + input_len > ctx->plaintext_len )
     {
         return MBEDTLS_ERR_CCM_BAD_INPUT;
     }
diff --git a/library/cipher.c b/library/cipher.c
index dc80189..0d9d710 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -29,6 +29,7 @@
 #include "cipher_wrap.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -74,27 +75,6 @@
 #define CIPHER_VALIDATE( cond )        \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/* Compare the contents of two buffers in constant time.
- * Returns 0 if the contents are bitwise identical, otherwise returns
- * a non-zero value.
- * This is currently only used by GCM and ChaCha20+Poly1305.
- */
-static int mbedtls_constant_time_memcmp( const void *v1, const void *v2,
-                                         size_t len )
-{
-    const unsigned char *p1 = (const unsigned char*) v1;
-    const unsigned char *p2 = (const unsigned char*) v2;
-    size_t i;
-    unsigned char diff;
-
-    for( diff = 0, i = 0; i < len; i++ )
-        diff |= p1[i] ^ p2[i];
-
-    return( (int)diff );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
 static int supported_init = 0;
 
 const int *mbedtls_cipher_list( void )
@@ -424,6 +404,31 @@
     }
 #endif
 
+#if defined(MBEDTLS_CCM_C)
+    if( MBEDTLS_MODE_CCM_STAR_NO_TAG == ctx->cipher_info->mode )
+    {
+        int set_lengths_result;
+        int ccm_star_mode;
+
+        set_lengths_result = mbedtls_ccm_set_lengths(
+                                (mbedtls_ccm_context *) ctx->cipher_ctx,
+                                0, 0, 0 );
+        if( set_lengths_result != 0 )
+            return set_lengths_result;
+
+        if( ctx->operation == MBEDTLS_DECRYPT )
+            ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT;
+        else if( ctx->operation == MBEDTLS_ENCRYPT )
+            ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT;
+        else
+            return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+
+        return( mbedtls_ccm_starts( (mbedtls_ccm_context *) ctx->cipher_ctx,
+                                    ccm_star_mode,
+                                    iv, iv_len ) );
+    }
+#endif
+
     if ( actual_iv_size != 0 )
     {
         memcpy( ctx->iv, iv, actual_iv_size );
@@ -560,6 +565,15 @@
     }
 #endif
 
+#if defined(MBEDTLS_CCM_C)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_CCM_STAR_NO_TAG )
+    {
+        return( mbedtls_ccm_update( (mbedtls_ccm_context *) ctx->cipher_ctx,
+                                    input, ilen,
+                                    output, ilen, olen ) );
+    }
+#endif
+
 #if defined(MBEDTLS_CHACHAPOLY_C)
     if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
     {
@@ -947,6 +961,7 @@
         MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
         MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
         MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_CCM_STAR_NO_TAG == ctx->cipher_info->mode ||
         MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
         MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
     {
@@ -1179,7 +1194,7 @@
         }
 
         /* Check the tag in "constant-time" */
-        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+        if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
 
         return( 0 );
@@ -1201,7 +1216,7 @@
         }
 
         /* Check the tag in "constant-time" */
-        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+        if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
             return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
 
         return( 0 );
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 5776d5e..7da7d9d 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -639,6 +639,39 @@
     16,
     &ccm_aes_info
 };
+
+static const mbedtls_cipher_info_t aes_128_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    128,
+    "AES-128-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    192,
+    "AES-192-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    256,
+    "AES-256-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
 #endif /* MBEDTLS_CCM_C */
 
 #endif /* MBEDTLS_AES_C */
@@ -1014,6 +1047,39 @@
     16,
     &ccm_camellia_info
 };
+
+static const mbedtls_cipher_info_t camellia_128_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    128,
+    "CAMELLIA-128-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    192,
+    "CAMELLIA-192-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    256,
+    "CAMELLIA-256-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
 #endif /* MBEDTLS_CCM_C */
 
 #endif /* MBEDTLS_CAMELLIA_C */
@@ -1390,6 +1456,39 @@
     16,
     &ccm_aria_info
 };
+
+static const mbedtls_cipher_info_t aria_128_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    128,
+    "ARIA-128-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    192,
+    "ARIA-192-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ccm_star_no_tag_info = {
+    MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG,
+    MBEDTLS_MODE_CCM_STAR_NO_TAG,
+    256,
+    "ARIA-256-CCM*-NO-TAG",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
 #endif /* MBEDTLS_CCM_C */
 
 #endif /* MBEDTLS_ARIA_C */
@@ -2055,6 +2154,9 @@
     { MBEDTLS_CIPHER_AES_128_CCM,          &aes_128_ccm_info },
     { MBEDTLS_CIPHER_AES_192_CCM,          &aes_192_ccm_info },
     { MBEDTLS_CIPHER_AES_256_CCM,          &aes_256_ccm_info },
+    { MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG,          &aes_128_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG,          &aes_192_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG,          &aes_256_ccm_star_no_tag_info },
 #endif
 #endif /* MBEDTLS_AES_C */
 
@@ -2086,6 +2188,9 @@
     { MBEDTLS_CIPHER_CAMELLIA_128_CCM,     &camellia_128_ccm_info },
     { MBEDTLS_CIPHER_CAMELLIA_192_CCM,     &camellia_192_ccm_info },
     { MBEDTLS_CIPHER_CAMELLIA_256_CCM,     &camellia_256_ccm_info },
+    { MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG,     &camellia_128_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG,     &camellia_192_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG,     &camellia_256_ccm_star_no_tag_info },
 #endif
 #endif /* MBEDTLS_CAMELLIA_C */
 
@@ -2117,6 +2222,9 @@
     { MBEDTLS_CIPHER_ARIA_128_CCM,     &aria_128_ccm_info },
     { MBEDTLS_CIPHER_ARIA_192_CCM,     &aria_192_ccm_info },
     { MBEDTLS_CIPHER_ARIA_256_CCM,     &aria_256_ccm_info },
+    { MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG,     &aria_128_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG,     &aria_192_ccm_star_no_tag_info },
+    { MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG,     &aria_256_ccm_star_no_tag_info },
 #endif
 #endif /* MBEDTLS_ARIA_C */
 
diff --git a/library/constant_time.c b/library/constant_time.c
new file mode 100644
index 0000000..9bb275c
--- /dev/null
+++ b/library/constant_time.c
@@ -0,0 +1,742 @@
+/**
+ *  Constant-time functions
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  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.
+ */
+
+ /*
+ * The following functions are implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+
+#include "common.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "ssl_misc.h"
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+
+#include <string.h>
+
+int mbedtls_ct_memcmp( const void *a,
+                       const void *b,
+                       size_t n )
+{
+    size_t i;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+    {
+        /* Read volatile data in order before computing diff.
+         * This avoids IAR compiler warning:
+         * 'the order of volatile accesses is undefined ..' */
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    return( (int)diff );
+}
+
+unsigned mbedtls_ct_uint_mask( unsigned value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+size_t mbedtls_ct_size_mask( size_t value )
+{
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "less than" comparison:
+ * - if \p x < \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      All-bits-one if \p x is less than \p y, otherwise zero.
+ */
+static size_t mbedtls_ct_size_mask_lt( size_t x,
+                                       size_t y )
+{
+    /* This has the most significant bit set if and only if x < y */
+    const size_t sub = x - y;
+
+    /* sub1 = (x < y) ? 1 : 0 */
+    const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
+
+    /* mask = (x < y) ? 0xff... : 0x00... */
+    const size_t mask = mbedtls_ct_size_mask( sub1 );
+
+    return( mask );
+}
+
+size_t mbedtls_ct_size_mask_ge( size_t x,
+                                size_t y )
+{
+    return( ~mbedtls_ct_size_mask_lt( x, y ) );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+                                  size_t y )
+{
+    /* diff = 0 if x == y, non-zero otherwise */
+    const size_t diff = x ^ y;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* diff_msb's most significant bit is equal to x != y */
+    const size_t diff_msb = ( diff | (size_t) -diff );
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /* diff1 = (x != y) ? 1 : 0 */
+    const unsigned diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+    return( 1 ^ diff1 );
+}
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Constant-flow "greater than" comparison:
+ * return x > y
+ *
+ * This is equivalent to \p x > \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x greater than \p y, otherwise 0.
+ */
+static unsigned mbedtls_ct_size_gt( size_t x,
+                                    size_t y )
+{
+    /* Return the sign bit (1 for negative) of (y - x). */
+    return( ( y - x ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+                                 const mbedtls_mpi_uint y )
+{
+    mbedtls_mpi_uint ret;
+    mbedtls_mpi_uint cond;
+
+    /*
+     * Check if the most significant bits (MSB) of the operands are different.
+     */
+    cond = ( x ^ y );
+    /*
+     * If the MSB are the same then the difference x-y will be negative (and
+     * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
+     */
+    ret = ( x - y ) & ~cond;
+    /*
+     * If the MSB are different, then the operand with the MSB of 1 is the
+     * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
+     * the MSB of y is 0.)
+     */
+    ret |= y & cond;
+
+
+    ret = ret >> ( sizeof( mbedtls_mpi_uint ) * 8 - 1 );
+
+    return (unsigned) ret;
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+unsigned mbedtls_ct_uint_if( unsigned condition,
+                             unsigned if1,
+                             unsigned if0 )
+{
+    unsigned mask = mbedtls_ct_uint_mask( condition );
+    return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Select between two sign values without branches.
+ *
+ * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
+ * operations in order to avoid branches.
+ *
+ * \note if1 and if0 must be either 1 or -1, otherwise the result
+ *       is undefined.
+ *
+ * \param condition     Condition to test.
+ * \param if1           The first sign; must be either +1 or -1.
+ * \param if0           The second sign; must be either +1 or -1.
+ *
+ * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
+ * */
+static int mbedtls_ct_cond_select_sign( unsigned char condition,
+                                        int if1,
+                                        int if0 )
+{
+    /* In order to avoid questions about what we can reasonably assume about
+     * the representations of signed integers, move everything to unsigned
+     * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
+    unsigned uif1 = if1 + 1;
+    unsigned uif0 = if0 + 1;
+
+    /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
+    const unsigned mask = condition << 1;
+
+    /* select uif1 or uif0 */
+    unsigned ur = ( uif0 & ~mask ) | ( uif1 & mask );
+
+    /* ur is now 0 or 2, convert back to -1 or +1 */
+    return( (int) ur - 1 );
+}
+
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+                                      mbedtls_mpi_uint *dest,
+                                      const mbedtls_mpi_uint *src,
+                                      unsigned char condition )
+{
+    size_t i;
+
+    /* MSVC has a warning about unary minus on unsigned integer types,
+     * but this is well-defined and precisely what we want to do here. */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+
+    /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
+    const mbedtls_mpi_uint mask = -condition;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    for( i = 0; i < n; i++ )
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Shift some data towards the left inside a buffer.
+ *
+ * `mbedtls_ct_mem_move_to_left(start, total, offset)` is functionally
+ * equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start     Pointer to the start of the buffer.
+ * \param total     Total size of the buffer.
+ * \param offset    Offset from which to copy \p total - \p offset bytes.
+ */
+static void mbedtls_ct_mem_move_to_left( void *start,
+                                         size_t total,
+                                         size_t offset )
+{
+    volatile unsigned char *buf = start;
+    size_t i, n;
+    if( total == 0 )
+        return;
+    for( i = 0; i < total; i++ )
+    {
+        unsigned no_op = mbedtls_ct_size_gt( total - offset, i );
+        /* The first `total - offset` passes are a no-op. The last
+         * `offset` passes shift the data one byte to the left and
+         * zero out the last byte. */
+        for( n = 0; n < total - 1; n++ )
+        {
+            unsigned char current = buf[n];
+            unsigned char next = buf[n+1];
+            buf[n] = mbedtls_ct_uint_if( no_op, current, next );
+        }
+        buf[total-1] = mbedtls_ct_uint_if( no_op, buf[total-1], 0 );
+    }
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+                              const unsigned char *src,
+                              size_t len,
+                              size_t c1,
+                              size_t c2 )
+{
+    /* mask = c1 == c2 ? 0xff : 0x00 */
+    const size_t equal = mbedtls_ct_size_bool_eq( c1, c2 );
+    const unsigned char mask = (unsigned char) mbedtls_ct_size_mask( equal );
+
+    /* dest[i] = c1 == c2 ? src[i] : dest[i] */
+    for( size_t i = 0; i < len; i++ )
+        dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+                               const unsigned char *src,
+                               size_t offset,
+                               size_t offset_min,
+                               size_t offset_max,
+                               size_t len )
+{
+    size_t offsetval;
+
+    for( offsetval = offset_min; offsetval <= offset_max; offsetval++ )
+    {
+        mbedtls_ct_memcpy_if_eq( dest, src + offsetval, len,
+                                 offsetval, offset );
+    }
+}
+
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+                     const unsigned char *add_data,
+                     size_t add_data_len,
+                     const unsigned char *data,
+                     size_t data_len_secret,
+                     size_t min_data_len,
+                     size_t max_data_len,
+                     unsigned char *output )
+{
+    /*
+     * This function breaks the HMAC abstraction and uses the md_clone()
+     * extension to the MD API in order to get constant-flow behaviour.
+     *
+     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
+     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
+     * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
+     *
+     * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
+     * minlen, then cloning the context, and for each byte up to maxlen
+     * finishing up the hash computation, keeping only the correct result.
+     *
+     * Then we only need to compute HASH(okey + inner_hash) and we're done.
+     */
+    const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
+    /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
+     * all of which have the same block size except SHA-384. */
+    const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
+    const unsigned char * const ikey = ctx->hmac_ctx;
+    const unsigned char * const okey = ikey + block_size;
+    const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
+
+    unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
+    mbedtls_md_context_t aux;
+    size_t offset;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    mbedtls_md_init( &aux );
+
+#define MD_CHK( func_call ) \
+    do {                    \
+        ret = (func_call);  \
+        if( ret != 0 )      \
+            goto cleanup;   \
+    } while( 0 )
+
+    MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
+
+    /* After hmac_start() of hmac_reset(), ikey has already been hashed,
+     * so we can start directly with the message */
+    MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
+    MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
+
+    /* For each possible length, compute the hash up to that point */
+    for( offset = min_data_len; offset <= max_data_len; offset++ )
+    {
+        MD_CHK( mbedtls_md_clone( &aux, ctx ) );
+        MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
+        /* Keep only the correct inner_hash in the output buffer */
+        mbedtls_ct_memcpy_if_eq( output, aux_out, hash_size,
+                                 offset, data_len_secret );
+
+        if( offset < max_data_len )
+            MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
+    }
+
+    /* The context needs to finish() before it starts() again */
+    MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
+
+    /* Now compute HASH(okey + inner_hash) */
+    MD_CHK( mbedtls_md_starts( ctx ) );
+    MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
+    MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
+    MD_CHK( mbedtls_md_finish( ctx, output ) );
+
+    /* Done, get ready for next time */
+    MD_CHK( mbedtls_md_hmac_reset( ctx ) );
+
+#undef MD_CHK
+
+cleanup:
+    mbedtls_md_free( &aux );
+    return( ret );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#define MPI_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
+                                  const mbedtls_mpi *Y,
+                                  unsigned char assign )
+{
+    int ret = 0;
+    size_t i;
+    mbedtls_mpi_uint limb_mask;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+    limb_mask = mbedtls_ct_mpi_uint_mask( assign );;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+
+    X->s = mbedtls_ct_cond_select_sign( assign, Y->s, X->s );
+
+    mbedtls_ct_mpi_uint_cond_assign( Y->n, X->p, Y->p, assign );
+
+    for( i = Y->n; i < X->n; i++ )
+        X->p[i] &= ~limb_mask;
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which whould lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
+                                mbedtls_mpi *Y,
+                                unsigned char swap )
+{
+    int ret, s;
+    size_t i;
+    mbedtls_mpi_uint limb_mask;
+    mbedtls_mpi_uint tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    if( X == Y )
+        return( 0 );
+
+    /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
+    limb_mask = mbedtls_ct_mpi_uint_mask( swap );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
+
+    s = X->s;
+    X->s = mbedtls_ct_cond_select_sign( swap, Y->s, X->s );
+    Y->s = mbedtls_ct_cond_select_sign( swap, s, Y->s );
+
+
+    for( i = 0; i < X->n; i++ )
+    {
+        tmp = X->p[i];
+        X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
+        Y->p[i] = ( Y->p[i] & ~limb_mask ) | (     tmp & limb_mask );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Compare signed values in constant time
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X,
+                           const mbedtls_mpi *Y,
+                           unsigned *ret )
+{
+    size_t i;
+    /* The value of any of these variables is either 0 or 1 at all times. */
+    unsigned cond, done, X_is_negative, Y_is_negative;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+    MPI_VALIDATE_RET( ret != NULL );
+
+    if( X->n != Y->n )
+        return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+    /*
+     * Set sign_N to 1 if N >= 0, 0 if N < 0.
+     * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
+     */
+    X_is_negative = ( X->s & 2 ) >> 1;
+    Y_is_negative = ( Y->s & 2 ) >> 1;
+
+    /*
+     * If the signs are different, then the positive operand is the bigger.
+     * That is if X is negative (X_is_negative == 1), then X < Y is true and it
+     * is false if X is positive (X_is_negative == 0).
+     */
+    cond = ( X_is_negative ^ Y_is_negative );
+    *ret = cond & X_is_negative;
+
+    /*
+     * This is a constant-time function. We might have the result, but we still
+     * need to go through the loop. Record if we have the result already.
+     */
+    done = cond;
+
+    for( i = X->n; i > 0; i-- )
+    {
+        /*
+         * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
+         * X and Y are negative.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = mbedtls_ct_mpi_uint_lt( Y->p[i - 1], X->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & X_is_negative;
+        done |= cond;
+
+        /*
+         * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
+         * X and Y are positive.
+         *
+         * Again even if we can make a decision, we just mark the result and
+         * the fact that we are done and continue looping.
+         */
+        cond = mbedtls_ct_mpi_uint_lt( X->p[i - 1], Y->p[i - 1] );
+        *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
+        done |= cond;
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( unsigned char *input,
+                                          size_t ilen,
+                                          unsigned char *output,
+                                          size_t output_max_len,
+                                          size_t *olen )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i, plaintext_max_size;
+
+    /* The following variables take sensitive values: their value must
+     * not leak into the observable behavior of the function other than
+     * the designated outputs (output, olen, return value). Otherwise
+     * this would open the execution of the function to
+     * side-channel-based variants of the Bleichenbacher padding oracle
+     * attack. Potential side channels include overall timing, memory
+     * access patterns (especially visible to an adversary who has access
+     * to a shared memory cache), and branches (especially visible to
+     * an adversary who has access to a shared code cache or to a shared
+     * branch predictor). */
+    size_t pad_count = 0;
+    unsigned bad = 0;
+    unsigned char pad_done = 0;
+    size_t plaintext_size = 0;
+    unsigned output_too_large;
+
+    plaintext_max_size = ( output_max_len > ilen - 11 ) ? ilen - 11
+                                                        : output_max_len;
+
+    /* Check and get padding length in constant time and constant
+     * memory trace. The first byte must be 0. */
+    bad |= input[0];
+
+
+    /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+     * where PS must be at least 8 nonzero bytes. */
+    bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
+
+    /* Read the whole buffer. Set pad_done to nonzero if we find
+     * the 0x00 byte and remember the padding length in pad_count. */
+    for( i = 2; i < ilen; i++ )
+    {
+        pad_done  |= ((input[i] | (unsigned char)-input[i]) >> 7) ^ 1;
+        pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+    }
+
+
+    /* If pad_done is still zero, there's no data, only unfinished padding. */
+    bad |= mbedtls_ct_uint_if( pad_done, 0, 1 );
+
+    /* There must be at least 8 bytes of padding. */
+    bad |= mbedtls_ct_size_gt( 8, pad_count );
+
+    /* If the padding is valid, set plaintext_size to the number of
+     * remaining bytes after stripping the padding. If the padding
+     * is invalid, avoid leaking this fact through the size of the
+     * output: use the maximum message size that fits in the output
+     * buffer. Do it without branches to avoid leaking the padding
+     * validity through timing. RSA keys are small enough that all the
+     * size_t values involved fit in unsigned int. */
+    plaintext_size = mbedtls_ct_uint_if(
+                        bad, (unsigned) plaintext_max_size,
+                        (unsigned) ( ilen - pad_count - 3 ) );
+
+    /* Set output_too_large to 0 if the plaintext fits in the output
+     * buffer and to 1 otherwise. */
+    output_too_large = mbedtls_ct_size_gt( plaintext_size,
+                                           plaintext_max_size );
+
+    /* Set ret without branches to avoid timing attacks. Return:
+     * - INVALID_PADDING if the padding is bad (bad != 0).
+     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+     *   plaintext does not fit in the output buffer.
+     * - 0 if the padding is correct. */
+    ret = - (int) mbedtls_ct_uint_if(
+                    bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+                    mbedtls_ct_uint_if( output_too_large,
+                                        - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+                                        0 ) );
+
+    /* If the padding is bad or the plaintext is too large, zero the
+     * data that we're about to copy to the output buffer.
+     * We need to copy the same amount of data
+     * from the same buffer whether the padding is good or not to
+     * avoid leaking the padding validity through overall timing or
+     * through memory or cache access patterns. */
+    bad = mbedtls_ct_uint_mask( bad | output_too_large );
+    for( i = 11; i < ilen; i++ )
+        input[i] &= ~bad;
+
+    /* If the plaintext is too large, truncate it to the buffer size.
+     * Copy anyway to avoid revealing the length through timing, because
+     * revealing the length is as bad as revealing the padding validity
+     * for a Bleichenbacher attack. */
+    plaintext_size = mbedtls_ct_uint_if( output_too_large,
+                                         (unsigned) plaintext_max_size,
+                                         (unsigned) plaintext_size );
+
+    /* Move the plaintext to the leftmost position where it can start in
+     * the working buffer, i.e. make it start plaintext_max_size from
+     * the end of the buffer. Do this with a memory access trace that
+     * does not depend on the plaintext size. After this move, the
+     * starting location of the plaintext is no longer sensitive
+     * information. */
+    mbedtls_ct_mem_move_to_left( input + ilen - plaintext_max_size,
+                                 plaintext_max_size,
+                                 plaintext_max_size - plaintext_size );
+
+    /* Finally copy the decrypted plaintext plus trailing zeros into the output
+     * buffer. If output_max_len is 0, then output may be an invalid pointer
+     * and the result of memcpy() would be undefined; prevent undefined
+     * behavior making sure to depend only on output_max_len (the size of the
+     * user-provided output buffer), which is independent from plaintext
+     * length, validity of padding, success of the decryption, and other
+     * secrets. */
+    if( output_max_len != 0 )
+        memcpy( output, input + ilen - plaintext_max_size, plaintext_max_size );
+
+    /* Report the amount of data we copied to the output buffer. In case
+     * of errors (bad padding or output too large), the value of *olen
+     * when this function returns is not specified. Making it equivalent
+     * to the good case limits the risks of leaking the padding validity. */
+    *olen = plaintext_size;
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
new file mode 100644
index 0000000..ac18b56
--- /dev/null
+++ b/library/constant_time_internal.h
@@ -0,0 +1,297 @@
+/**
+ *  Constant-time functions
+ *
+ *  Copyright The Mbed TLS Contributors
+ *  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.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
+#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "ssl_misc.h"
+#endif
+
+#include <stddef.h>
+
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (unsigned) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+unsigned mbedtls_ct_uint_mask( unsigned value );
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (size_t) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+size_t mbedtls_ct_size_mask( size_t value );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value     The value to analyze.
+ *
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "greater or equal" comparison:
+ * - if \p x >= \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      All-bits-one if \p x is greater or equal than \p y,
+ *              otherwise zero.
+ */
+size_t mbedtls_ct_size_mask_ge( size_t x,
+                                size_t y );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+/** Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This is equivalent to \p x == \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x equals to \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+                                  size_t y );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Decide if an integer is less than the other, without branches.
+ *
+ * This is equivalent to \p x < \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x     The first value to analyze.
+ * \param y     The second value to analyze.
+ *
+ * \return      1 if \p x is less than \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+                                 const mbedtls_mpi_uint y );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+/** Choose between two integer values without branches.
+ *
+ * This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param condition     Condition to test.
+ * \param if1           Value to use if \p condition is nonzero.
+ * \param if0           Value to use if \p condition is zero.
+ *
+ * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
+ */
+unsigned mbedtls_ct_uint_if( unsigned condition,
+                             unsigned if1,
+                             unsigned if0 );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Conditionally assign a value without branches.
+ *
+ * This is equivalent to `if ( condition ) dest = src`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param n             \p dest and \p src must be arrays of limbs of size n.
+ * \param dest          The MPI to conditionally assign to. This must point
+ *                      to an initialized MPI.
+ * \param src           The MPI to be assigned from. This must point to an
+ *                      initialized MPI.
+ * \param condition     Condition to test, must be 0 or 1.
+ */
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+                                      mbedtls_mpi_uint *dest,
+                                      const mbedtls_mpi_uint *src,
+                                      unsigned char condition );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Conditional memcpy without branches.
+ *
+ * This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param dest      The pointer to conditionally copy to.
+ * \param src       The pointer to copy from. Shouldn't overlap with \p dest.
+ * \param len       The number of bytes to copy.
+ * \param c1        The first value to analyze in the condition.
+ * \param c2        The second value to analyze in the condition.
+ */
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+                              const unsigned char *src,
+                              size_t len,
+                              size_t c1, size_t c2 );
+
+/** Copy data from a secret position with constant flow.
+ *
+ * This function copies \p len bytes from \p src_base + \p offset_secret to \p
+ * dst, with a code flow and memory access pattern that does not depend on \p
+ * offset_secret, but only on \p offset_min, \p offset_max and \p len.
+ * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
+ *
+ * \param dest          The destination buffer. This must point to a writable
+ *                      buffer of at least \p len bytes.
+ * \param src           The base of the source buffer. This must point to a
+ *                      readable buffer of at least \p offset_max + \p len
+ *                      bytes. Shouldn't overlap with \p dest.
+ * \param offset        The offset in the source buffer from which to copy.
+ *                      This must be no less than \p offset_min and no greater
+ *                      than \p offset_max.
+ * \param offset_min    The minimal value of \p offset.
+ * \param offset_max    The maximal value of \p offset.
+ * \param len           The number of bytes to copy.
+ */
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+                               const unsigned char *src,
+                               size_t offset,
+                               size_t offset_min,
+                               size_t offset_max,
+                               size_t len );
+
+/** Compute the HMAC of variable-length data with constant flow.
+ *
+ * This function computes the HMAC of the concatenation of \p add_data and \p
+ * data, and does with a code flow and memory access pattern that does not
+ * depend on \p data_len_secret, but only on \p min_data_len and \p
+ * max_data_len. In particular, this function always reads exactly \p
+ * max_data_len bytes from \p data.
+ *
+ * \param ctx               The HMAC context. It must have keys configured
+ *                          with mbedtls_md_hmac_starts() and use one of the
+ *                          following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
+ *                          It is reset using mbedtls_md_hmac_reset() after
+ *                          the computation is complete to prepare for the
+ *                          next computation.
+ * \param add_data          The first part of the message whose HMAC is being
+ *                          calculated. This must point to a readable buffer
+ *                          of \p add_data_len bytes.
+ * \param add_data_len      The length of \p add_data in bytes.
+ * \param data              The buffer containing the second part of the
+ *                          message. This must point to a readable buffer
+ *                          of \p max_data_len bytes.
+ * \param data_len_secret   The length of the data to process in \p data.
+ *                          This must be no less than \p min_data_len and no
+ *                          greater than \p max_data_len.
+ * \param min_data_len      The minimal length of the second part of the
+ *                          message, read from \p data.
+ * \param max_data_len      The maximal length of the second part of the
+ *                          message, read from \p data.
+ * \param output            The HMAC will be written here. This must point to
+ *                          a writable buffer of sufficient size to hold the
+ *                          HMAC value.
+ *
+ * \retval 0 on success.
+ * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
+ *         The hardware accelerator failed.
+ */
+int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
+                     const unsigned char *add_data,
+                     size_t add_data_len,
+                     const unsigned char *data,
+                     size_t data_len_secret,
+                     size_t min_data_len,
+                     size_t max_data_len,
+                     unsigned char *output );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
+ *  operation (EME-PKCS1-v1_5 decoding).
+ *
+ * \note The return value from this function is a sensitive value
+ *       (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
+ *       in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
+ *       is often a situation that an attacker can provoke and leaking which
+ *       one is the result is precisely the information the attacker wants.
+ *
+ * \param input          The input buffer which is the payload inside PKCS#1v1.5
+ *                       encryption padding, called the "encoded message EM"
+ *                       by the terminology.
+ * \param ilen           The length of the payload in the \p input buffer.
+ * \param output         The buffer for the payload, called "message M" by the
+ *                       PKCS#1 terminology. This must be a writable buffer of
+ *                       length \p output_max_len bytes.
+ * \param olen           The address at which to store the length of
+ *                       the payload. This must not be \c NULL.
+ * \param output_max_len The length in bytes of the output buffer \p output.
+ *
+ * \return      \c 0 on success.
+ * \return      #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+ *              The output buffer is too small for the unpadded payload.
+ * \return      #MBEDTLS_ERR_RSA_INVALID_PADDING
+ *              The input doesn't contain properly formatted padding.
+ */
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( unsigned char *input,
+                                          size_t ilen,
+                                          unsigned char *output,
+                                          size_t output_max_len,
+                                          size_t *olen );
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
diff --git a/library/gcm.c b/library/gcm.c
index 6d62564..8505cf4 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -254,6 +254,7 @@
     size_t i;
     const unsigned char *p;
     size_t use_len, olen = 0;
+    uint64_t iv_bits;
 
     GCM_VALIDATE_RET( ctx != NULL );
     GCM_VALIDATE_RET( iv != NULL );
@@ -278,7 +279,8 @@
     else
     {
         memset( work_buf, 0x00, 16 );
-        MBEDTLS_PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
+        iv_bits = (uint64_t)iv_len * 8;
+        MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
 
         p = iv;
         while( iv_len > 0 )
diff --git a/library/nist_kw.c b/library/nist_kw.c
index e2ab256..1aea0b6 100644
--- a/library/nist_kw.c
+++ b/library/nist_kw.c
@@ -34,6 +34,7 @@
 #include "mbedtls/nist_kw.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #include <stdint.h>
 #include <string.h>
@@ -52,26 +53,6 @@
 #define KW_SEMIBLOCK_LENGTH    8
 #define MIN_SEMIBLOCKS_COUNT   3
 
-/* constant-time buffer comparison */
-static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
-{
-    size_t i;
-    volatile const unsigned char *A = (volatile const unsigned char *) a;
-    volatile const unsigned char *B = (volatile const unsigned char *) b;
-    volatile unsigned char diff = 0;
-
-    for( i = 0; i < n; i++ )
-    {
-        /* Read volatile data in order before computing diff.
-         * This avoids IAR compiler warning:
-         * 'the order of volatile accesses is undefined ..' */
-        unsigned char x = A[i], y = B[i];
-        diff |= x ^ y;
-    }
-
-    return( diff );
-}
-
 /*! The 64-bit default integrity check value (ICV) for KW mode. */
 static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
 /*! The 32-bit default integrity check value (ICV) for KWP mode. */
@@ -398,7 +379,7 @@
             goto cleanup;
 
         /* Check ICV in "constant-time" */
-        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
+        diff = mbedtls_ct_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
 
         if( diff != 0 )
         {
@@ -447,7 +428,7 @@
         }
 
         /* Check ICV in "constant-time" */
-        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
+        diff = mbedtls_ct_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
 
         if( diff != 0 )
         {
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index c4bcddc..0a04ba1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3595,7 +3595,12 @@
       .core = slot->attr
     };
 
-    if( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) )
+    if( alg == PSA_ALG_CCM_STAR_NO_TAG && input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ) )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
+    }
+    else if ( input_length < PSA_CIPHER_IV_LENGTH( slot->attr.type, alg ) )
     {
         status = PSA_ERROR_INVALID_ARGUMENT;
         goto exit;
@@ -3653,13 +3658,15 @@
         case PSA_ALG_CHACHA20_POLY1305:
             if( nonce_length == 12 )
                 return( PSA_SUCCESS );
+            else if( nonce_length == 8 )
+                return( PSA_ERROR_NOT_SUPPORTED );
             break;
 #endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
         default:
-            break;
+            return( PSA_ERROR_NOT_SUPPORTED );
     }
 
-    return( PSA_ERROR_NOT_SUPPORTED );
+    return( PSA_ERROR_INVALID_ARGUMENT );
 }
 
 psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key,
@@ -4758,6 +4765,9 @@
     if( psa_get_key_bits( attributes ) == 0 )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
+    if( operation->alg == PSA_ALG_NONE )
+        return( PSA_ERROR_BAD_STATE );
+
     if( ! operation->can_output_key )
         return( PSA_ERROR_NOT_PERMITTED );
 
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index ce8ab5c..07c6a00 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -92,6 +92,9 @@
             case PSA_ALG_CBC_PKCS7:
                 mode = MBEDTLS_MODE_CBC;
                 break;
+            case PSA_ALG_CCM_STAR_NO_TAG:
+                mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
+                break;
             case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
                 mode = MBEDTLS_MODE_CCM;
                 break;
diff --git a/library/rsa.c b/library/rsa.c
index e818e6d..e3ec056 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -44,6 +44,8 @@
 #include "mbedtls/oid.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -72,22 +74,6 @@
 #define RSA_VALIDATE( cond )                                           \
     MBEDTLS_INTERNAL_VALIDATE( cond )
 
-#if defined(MBEDTLS_PKCS1_V15)
-/* constant-time buffer comparison */
-static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
-{
-    size_t i;
-    const unsigned char *A = (const unsigned char *) a;
-    const unsigned char *B = (const unsigned char *) b;
-    unsigned char diff = 0;
-
-    for( i = 0; i < n; i++ )
-        diff |= A[i] ^ B[i];
-
-    return( diff );
-}
-#endif /* MBEDTLS_PKCS1_V15 */
-
 int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
                         const mbedtls_mpi *N,
                         const mbedtls_mpi *P, const mbedtls_mpi *Q,
@@ -1473,97 +1459,6 @@
 #endif /* MBEDTLS_PKCS1_V21 */
 
 #if defined(MBEDTLS_PKCS1_V15)
-/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
- *
- * \param value     The value to analyze.
- * \return          Zero if \p value is zero, otherwise all-bits-one.
- */
-static unsigned all_or_nothing_int( unsigned value )
-{
-    /* MSVC has a warning about unary minus on unsigned, but this is
-     * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/** Check whether a size is out of bounds, without branches.
- *
- * This is equivalent to `size > max`, but is likely to be compiled to
- * to code using bitwise operation rather than a branch.
- *
- * \param size      Size to check.
- * \param max       Maximum desired value for \p size.
- * \return          \c 0 if `size <= max`.
- * \return          \c 1 if `size > max`.
- */
-static unsigned size_greater_than( size_t size, size_t max )
-{
-    /* Return the sign bit (1 for negative) of (max - size). */
-    return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
-}
-
-/** Choose between two integer values, without branches.
- *
- * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
- * to code using bitwise operation rather than a branch.
- *
- * \param cond      Condition to test.
- * \param if1       Value to use if \p cond is nonzero.
- * \param if0       Value to use if \p cond is zero.
- * \return          \c if1 if \p cond is nonzero, otherwise \c if0.
- */
-static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
-{
-    unsigned mask = all_or_nothing_int( cond );
-    return( ( mask & if1 ) | (~mask & if0 ) );
-}
-
-/** Shift some data towards the left inside a buffer without leaking
- * the length of the data through side channels.
- *
- * `mem_move_to_left(start, total, offset)` is functionally equivalent to
- * ```
- * memmove(start, start + offset, total - offset);
- * memset(start + offset, 0, total - offset);
- * ```
- * but it strives to use a memory access pattern (and thus total timing)
- * that does not depend on \p offset. This timing independence comes at
- * the expense of performance.
- *
- * \param start     Pointer to the start of the buffer.
- * \param total     Total size of the buffer.
- * \param offset    Offset from which to copy \p total - \p offset bytes.
- */
-static void mem_move_to_left( void *start,
-                              size_t total,
-                              size_t offset )
-{
-    volatile unsigned char *buf = start;
-    size_t i, n;
-    if( total == 0 )
-        return;
-    for( i = 0; i < total; i++ )
-    {
-        unsigned no_op = size_greater_than( total - offset, i );
-        /* The first `total - offset` passes are a no-op. The last
-         * `offset` passes shift the data one byte to the left and
-         * zero out the last byte. */
-        for( n = 0; n < total - 1; n++ )
-        {
-            unsigned char current = buf[n];
-            unsigned char next = buf[n+1];
-            buf[n] = if_int( no_op, current, next );
-        }
-        buf[total-1] = if_int( no_op, buf[total-1], 0 );
-    }
-}
-
 /*
  * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
  */
@@ -1576,23 +1471,8 @@
                                  size_t output_max_len )
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t ilen, i, plaintext_max_size;
+    size_t ilen;
     unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
-    /* The following variables take sensitive values: their value must
-     * not leak into the observable behavior of the function other than
-     * the designated outputs (output, olen, return value). Otherwise
-     * this would open the execution of the function to
-     * side-channel-based variants of the Bleichenbacher padding oracle
-     * attack. Potential side channels include overall timing, memory
-     * access patterns (especially visible to an adversary who has access
-     * to a shared memory cache), and branches (especially visible to
-     * an adversary who has access to a shared code cache or to a shared
-     * branch predictor). */
-    size_t pad_count = 0;
-    unsigned bad = 0;
-    unsigned char pad_done = 0;
-    size_t plaintext_size = 0;
-    unsigned output_too_large;
 
     RSA_VALIDATE_RET( ctx != NULL );
     RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
@@ -1600,9 +1480,6 @@
     RSA_VALIDATE_RET( olen != NULL );
 
     ilen = ctx->len;
-    plaintext_max_size = ( output_max_len > ilen - 11 ?
-                           ilen - 11 :
-                           output_max_len );
 
     if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
         return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1615,98 +1492,8 @@
     if( ret != 0 )
         goto cleanup;
 
-    /* Check and get padding length in constant time and constant
-     * memory trace. The first byte must be 0. */
-    bad |= buf[0];
-
-
-    /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
-        * where PS must be at least 8 nonzero bytes. */
-    bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
-
-    /* Read the whole buffer. Set pad_done to nonzero if we find
-        * the 0x00 byte and remember the padding length in pad_count. */
-    for( i = 2; i < ilen; i++ )
-    {
-        pad_done  |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
-        pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
-    }
-
-
-    /* If pad_done is still zero, there's no data, only unfinished padding. */
-    bad |= if_int( pad_done, 0, 1 );
-
-    /* There must be at least 8 bytes of padding. */
-    bad |= size_greater_than( 8, pad_count );
-
-    /* If the padding is valid, set plaintext_size to the number of
-     * remaining bytes after stripping the padding. If the padding
-     * is invalid, avoid leaking this fact through the size of the
-     * output: use the maximum message size that fits in the output
-     * buffer. Do it without branches to avoid leaking the padding
-     * validity through timing. RSA keys are small enough that all the
-     * size_t values involved fit in unsigned int. */
-    plaintext_size = if_int( bad,
-                             (unsigned) plaintext_max_size,
-                             (unsigned) ( ilen - pad_count - 3 ) );
-
-    /* Set output_too_large to 0 if the plaintext fits in the output
-     * buffer and to 1 otherwise. */
-    output_too_large = size_greater_than( plaintext_size,
-                                          plaintext_max_size );
-
-    /* Set ret without branches to avoid timing attacks. Return:
-     * - INVALID_PADDING if the padding is bad (bad != 0).
-     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
-     *   plaintext does not fit in the output buffer.
-     * - 0 if the padding is correct. */
-    ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
-                  if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
-                          0 ) );
-
-    /* If the padding is bad or the plaintext is too large, zero the
-     * data that we're about to copy to the output buffer.
-     * We need to copy the same amount of data
-     * from the same buffer whether the padding is good or not to
-     * avoid leaking the padding validity through overall timing or
-     * through memory or cache access patterns. */
-    bad = all_or_nothing_int( bad | output_too_large );
-    for( i = 11; i < ilen; i++ )
-        buf[i] &= ~bad;
-
-    /* If the plaintext is too large, truncate it to the buffer size.
-     * Copy anyway to avoid revealing the length through timing, because
-     * revealing the length is as bad as revealing the padding validity
-     * for a Bleichenbacher attack. */
-    plaintext_size = if_int( output_too_large,
-                             (unsigned) plaintext_max_size,
-                             (unsigned) plaintext_size );
-
-    /* Move the plaintext to the leftmost position where it can start in
-     * the working buffer, i.e. make it start plaintext_max_size from
-     * the end of the buffer. Do this with a memory access trace that
-     * does not depend on the plaintext size. After this move, the
-     * starting location of the plaintext is no longer sensitive
-     * information. */
-    mem_move_to_left( buf + ilen - plaintext_max_size,
-                      plaintext_max_size,
-                      plaintext_max_size - plaintext_size );
-
-    /* Finally copy the decrypted plaintext plus trailing zeros into the output
-     * buffer. If output_max_len is 0, then output may be an invalid pointer
-     * and the result of memcpy() would be undefined; prevent undefined
-     * behavior making sure to depend only on output_max_len (the size of the
-     * user-provided output buffer), which is independent from plaintext
-     * length, validity of padding, success of the decryption, and other
-     * secrets. */
-    if( output_max_len != 0 )
-        memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
-
-    /* Report the amount of data we copied to the output buffer. In case
-     * of errors (bad padding or output too large), the value of *olen
-     * when this function returns is not specified. Making it equivalent
-     * to the good case limits the risks of leaking the padding validity. */
-    *olen = plaintext_size;
+    ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( buf, ilen,
+                                                output, output_max_len, olen );
 
 cleanup:
     mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -2100,7 +1887,7 @@
     MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
     MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
 
-    if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+    if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
     {
         ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
         goto cleanup;
@@ -2372,8 +2159,8 @@
      * Compare
      */
 
-    if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
-                                      sig_len ) ) != 0 )
+    if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
+                                              sig_len ) ) != 0 )
     {
         ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
         goto cleanup;
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 9fc8041..68d3033 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -33,6 +33,7 @@
 #include "ssl_misc.h"
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "mbedtls/psa_util.h"
@@ -89,10 +90,10 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
-                                   unsigned char *buf,
-                                   const unsigned char *end,
-                                   size_t *olen )
+int mbedtls_ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    const unsigned char *end,
+                                    size_t *olen )
 {
     unsigned char *p = buf;
     size_t hostname_len;
@@ -1168,10 +1169,10 @@
     MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
 
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
-    if( ( ret = ssl_write_hostname_ext( ssl, p + 2 + ext_len,
-                                        end, &olen ) ) != 0 )
+    if( ( ret = mbedtls_ssl_write_hostname_ext( ssl, p + 2 + ext_len,
+                                                end, &olen ) ) != 0 )
     {
-        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_hostname_ext", ret );
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_hostname_ext", ret );
         return( ret );
     }
     ext_len += olen;
@@ -1356,9 +1357,9 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len * 2 ||
             buf[0] !=     ssl->verify_data_len * 2 ||
-            mbedtls_ssl_safer_memcmp( buf + 1,
+            mbedtls_ct_memcmp( buf + 1,
                           ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
-            mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
+            mbedtls_ct_memcmp( buf + 1 + ssl->verify_data_len,
                           ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 986b141..7516786 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -36,6 +36,7 @@
 #include "ssl_misc.h"
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -223,7 +224,7 @@
     if( ret != 0 )
         return( ret );
 
-    if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+    if( mbedtls_ct_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
         return( -1 );
 
 #if defined(MBEDTLS_HAVE_TIME)
diff --git a/library/ssl_invasive.h b/library/ssl_invasive.h
deleted file mode 100644
index babbc27..0000000
--- a/library/ssl_invasive.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * \file ssl_invasive.h
- *
- * \brief SSL module: interfaces for invasive testing only.
- *
- * The interfaces in this file are intended for testing purposes only.
- * They SHOULD NOT be made available in library integrations except when
- * building the library for testing.
- */
-/*
- *  Copyright The Mbed TLS Contributors
- *  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.
- */
-#ifndef MBEDTLS_SSL_INVASIVE_H
-#define MBEDTLS_SSL_INVASIVE_H
-
-#include "common.h"
-#include "mbedtls/md.h"
-
-#if defined(MBEDTLS_TEST_HOOKS) &&              \
-    defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
-/** \brief Compute the HMAC of variable-length data with constant flow.
- *
- * This function computes the HMAC of the concatenation of \p add_data and \p
- * data, and does with a code flow and memory access pattern that does not
- * depend on \p data_len_secret, but only on \p min_data_len and \p
- * max_data_len. In particular, this function always reads exactly \p
- * max_data_len bytes from \p data.
- *
- * \param ctx               The HMAC context. It must have keys configured
- *                          with mbedtls_md_hmac_starts() and use one of the
- *                          following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
- *                          It is reset using mbedtls_md_hmac_reset() after
- *                          the computation is complete to prepare for the
- *                          next computation.
- * \param add_data          The additional data prepended to \p data. This
- *                          must point to a readable buffer of \p add_data_len
- *                          bytes.
- * \param add_data_len      The length of \p add_data in bytes.
- * \param data              The data appended to \p add_data. This must point
- *                          to a readable buffer of \p max_data_len bytes.
- * \param data_len_secret   The length of the data to process in \p data.
- *                          This must be no less than \p min_data_len and no
- *                          greater than \p max_data_len.
- * \param min_data_len      The minimal length of \p data in bytes.
- * \param max_data_len      The maximal length of \p data in bytes.
- * \param output            The HMAC will be written here. This must point to
- *                          a writable buffer of sufficient size to hold the
- *                          HMAC value.
- *
- * \retval 0
- *         Success.
- * \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
- *         The hardware accelerator failed.
- */
-int mbedtls_ssl_cf_hmac(
-        mbedtls_md_context_t *ctx,
-        const unsigned char *add_data, size_t add_data_len,
-        const unsigned char *data, size_t data_len_secret,
-        size_t min_data_len, size_t max_data_len,
-        unsigned char *output );
-
-/** \brief Copy data from a secret position with constant flow.
- *
- * This function copies \p len bytes from \p src_base + \p offset_secret to \p
- * dst, with a code flow and memory access pattern that does not depend on \p
- * offset_secret, but only on \p offset_min, \p offset_max and \p len.
- *
- * \param dst           The destination buffer. This must point to a writable
- *                      buffer of at least \p len bytes.
- * \param src_base      The base of the source buffer. This must point to a
- *                      readable buffer of at least \p offset_max + \p len
- *                      bytes.
- * \param offset_secret The offset in the source buffer from which to copy.
- *                      This must be no less than \p offset_min and no greater
- *                      than \p offset_max.
- * \param offset_min    The minimal value of \p offset_secret.
- * \param offset_max    The maximal value of \p offset_secret.
- * \param len           The number of bytes to copy.
- */
-void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
-                                   const unsigned char *src_base,
-                                   size_t offset_secret,
-                                   size_t offset_min, size_t offset_max,
-                                   size_t len );
-#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
-
-#endif /* MBEDTLS_SSL_INVASIVE_H */
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index c7d966b..36a0712 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -307,8 +307,6 @@
       + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
 #endif
 
-#define MBEDTLS_TLS1_3_MD_MAX_SIZE         MBEDTLS_MD_MAX_SIZE
-
 #define MBEDTLS_CLIENT_HELLO_RANDOM_LEN 32
 #define MBEDTLS_SERVER_HELLO_RANDOM_LEN 32
 
@@ -522,14 +520,6 @@
     unsigned char server_handshake_traffic_secret[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
 } mbedtls_ssl_tls1_3_handshake_secrets;
 
-typedef struct
-{
-    unsigned char client_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
-    unsigned char server_application_traffic_secret_N[ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
-    unsigned char exporter_master_secret             [ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
-    unsigned char resumption_master_secret           [ MBEDTLS_TLS1_3_MD_MAX_SIZE ];
-} mbedtls_ssl_tls1_3_application_secrets;
-
 /*
  * This structure contains the parameters only needed during handshake.
  */
@@ -719,6 +709,38 @@
                                 * but can be overwritten by the HRR. */
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
+    /*
+     * State-local variables used during the processing
+     * of a specific handshake state.
+     */
+    union
+    {
+        /* Outgoing Finished message */
+        struct
+        {
+            uint8_t preparation_done;
+
+            /* Buffer holding digest of the handshake up to
+             * but excluding the outgoing finished message. */
+            unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+            size_t digest_len;
+        } finished_out;
+
+        /* Incoming Finished message */
+        struct
+        {
+            uint8_t preparation_done;
+
+            /* Buffer holding digest of the handshake up to but
+             * excluding the peer's incoming finished message. */
+            unsigned char digest[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+            size_t digest_len;
+        } finished_in;
+
+    } state_local;
+
+    /* End of state-local variables. */
+
     mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
 
     size_t pmslen;                      /*!<  premaster length        */
@@ -1037,24 +1059,16 @@
 void mbedtls_ssl_set_outbound_transform( mbedtls_ssl_context *ssl,
                                          mbedtls_ssl_transform *transform );
 
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+int mbedtls_ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    const unsigned char *end,
+                                    size_t *olen );
+#endif
+
 int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
 int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
 void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-/**
- * \brief           TLS 1.3 client side state machine entry
- *
- * \param ssl       SSL context
- */
-int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl );
-
-/**
- * \brief           TLS 1.3 server side state machine entry
- *
- * \param ssl       SSL context
- */
-int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl );
-#endif
 
 int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
 
@@ -1355,26 +1369,6 @@
 int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
                               const mbedtls_ssl_session *src );
 
-/* constant-time buffer comparison */
-static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
-{
-    size_t i;
-    volatile const unsigned char *A = (volatile const unsigned char *) a;
-    volatile const unsigned char *B = (volatile const unsigned char *) b;
-    volatile unsigned char diff = 0;
-
-    for( i = 0; i < n; i++ )
-    {
-        /* Read volatile data in order before computing diff.
-         * This avoids IAR compiler warning:
-         * 'the order of volatile accesses is undefined ..' */
-        unsigned char x = A[i], y = B[i];
-        diff |= x ^ y;
-    }
-
-    return( diff );
-}
-
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 /* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */
 int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
@@ -1455,7 +1449,72 @@
 void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
 
+/**
+ * ssl utils functions for checking configuration.
+ */
+
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+static inline int mbedtls_ssl_conf_is_tls13_only( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static inline int mbedtls_ssl_conf_is_tls12_only( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_config *conf )
+{
+    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
+        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL*/
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_tls13_write_finished_message( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief           TLS 1.3 client side state machine entry
+ *
+ * \param ssl       SSL context
+ */
+int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief           TLS 1.3 server side state machine entry
+ *
+ * \param ssl       SSL context
+ */
+int mbedtls_ssl_tls13_handshake_server_step( mbedtls_ssl_context *ssl );
+
 
 /*
  * Helper functions around key exchange modes.
@@ -1543,56 +1602,6 @@
                    MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL ) );
 }
 
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
-
-/**
- * ssl utils functions for checking configuration.
- */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-static inline int mbedtls_ssl_conf_is_tls13_only( const mbedtls_ssl_config *conf )
-{
-    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 &&
-        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
-    {
-        return( 1 );
-    }
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-static inline int mbedtls_ssl_conf_is_tls12_only( const mbedtls_ssl_config *conf )
-{
-    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
-        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
-    {
-        return( 1 );
-    }
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_config *conf )
-{
-    if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 &&
-        conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
-        conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
-    {
-        return( 1 );
-    }
-    return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL*/
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-
 /*
  * Helper functions for NamedGroup.
  */
@@ -1639,6 +1648,11 @@
 int mbedtls_ssl_tls13_process_certificate( mbedtls_ssl_context *ssl );
 
 /*
+ * Generic handler of Certificate Verify
+ */
+int mbedtls_ssl_tls13_process_certificate_verify( mbedtls_ssl_context *ssl );
+
+/*
  * Write TLS 1.3 handshake message tail
  */
 int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl,
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 3795c65..286294f 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -40,8 +40,8 @@
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/version.h"
-
-#include "ssl_invasive.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -961,242 +961,6 @@
     return( 0 );
 }
 
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
-/*
- * Turn a bit into a mask:
- * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1
- * - if bit == 0, return the all-bits 0 mask, aka 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_from_bit( size_t bit )
-{
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    return -bit;
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/*
- * Constant-flow mask generation for "less than" comparison:
- * - if x < y,  return all bits 1, that is (size_t) -1
- * - otherwise, return all bits 0, that is 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_lt( size_t x, size_t y )
-{
-    /* This has the most significant bit set if and only if x < y */
-    const size_t sub = x - y;
-
-    /* sub1 = (x < y) ? 1 : 0 */
-    const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
-
-    /* mask = (x < y) ? 0xff... : 0x00... */
-    const size_t mask = mbedtls_ssl_cf_mask_from_bit( sub1 );
-
-    return( mask );
-}
-
-/*
- * Constant-flow mask generation for "greater or equal" comparison:
- * - if x >= y, return all bits 1, that is (size_t) -1
- * - otherwise, return all bits 0, that is 0
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations using masks.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_mask_ge( size_t x, size_t y )
-{
-    return( ~mbedtls_ssl_cf_mask_lt( x, y ) );
-}
-
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_ssl_cf_bool_eq( size_t x, size_t y )
-{
-    /* diff = 0 if x == y, non-zero otherwise */
-    const size_t diff = x ^ y;
-
-    /* MSVC has a warning about unary minus on unsigned integer types,
-     * but this is well-defined and precisely what we want to do here. */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-
-    /* diff_msb's most significant bit is equal to x != y */
-    const size_t diff_msb = ( diff | -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
-    /* diff1 = (x != y) ? 1 : 0 */
-    const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
-    return( 1 ^ diff1 );
-}
-
-/*
- * Constant-flow conditional memcpy:
- *  - if c1 == c2, equivalent to memcpy(dst, src, len),
- *  - otherwise, a no-op,
- * but with execution flow independent of the values of c1 and c2.
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
-                                         const unsigned char *src,
-                                         size_t len,
-                                         size_t c1, size_t c2 )
-{
-    /* mask = c1 == c2 ? 0xff : 0x00 */
-    const size_t equal = mbedtls_ssl_cf_bool_eq( c1, c2 );
-    const unsigned char mask = (unsigned char) mbedtls_ssl_cf_mask_from_bit( equal );
-
-    /* dst[i] = c1 == c2 ? src[i] : dst[i] */
-    for( size_t i = 0; i < len; i++ )
-        dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask );
-}
-
-/*
- * Compute HMAC of variable-length data with constant flow.
- *
- * Only works with MD-5, SHA-1, SHA-256 and SHA-384.
- * (Otherwise, computation of block_size needs to be adapted.)
- */
-MBEDTLS_STATIC_TESTABLE int mbedtls_ssl_cf_hmac(
-        mbedtls_md_context_t *ctx,
-        const unsigned char *add_data, size_t add_data_len,
-        const unsigned char *data, size_t data_len_secret,
-        size_t min_data_len, size_t max_data_len,
-        unsigned char *output )
-{
-    /*
-     * This function breaks the HMAC abstraction and uses the md_clone()
-     * extension to the MD API in order to get constant-flow behaviour.
-     *
-     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
-     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
-     * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
-     *
-     * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
-     * minlen, then cloning the context, and for each byte up to maxlen
-     * finishing up the hash computation, keeping only the correct result.
-     *
-     * Then we only need to compute HASH(okey + inner_hash) and we're done.
-     */
-    const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
-    /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
-     * all of which have the same block size except SHA-384. */
-    const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
-    const unsigned char * const ikey = ctx->hmac_ctx;
-    const unsigned char * const okey = ikey + block_size;
-    const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
-
-    unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
-    mbedtls_md_context_t aux;
-    size_t offset;
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
-    mbedtls_md_init( &aux );
-
-#define MD_CHK( func_call ) \
-    do {                    \
-        ret = (func_call);  \
-        if( ret != 0 )      \
-            goto cleanup;   \
-    } while( 0 )
-
-    MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
-
-    /* After hmac_start() of hmac_reset(), ikey has already been hashed,
-     * so we can start directly with the message */
-    MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
-    MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
-
-    /* For each possible length, compute the hash up to that point */
-    for( offset = min_data_len; offset <= max_data_len; offset++ )
-    {
-        MD_CHK( mbedtls_md_clone( &aux, ctx ) );
-        MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
-        /* Keep only the correct inner_hash in the output buffer */
-        mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size,
-                                     offset, data_len_secret );
-
-        if( offset < max_data_len )
-            MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
-    }
-
-    /* The context needs to finish() before it starts() again */
-    MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
-
-    /* Now compute HASH(okey + inner_hash) */
-    MD_CHK( mbedtls_md_starts( ctx ) );
-    MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
-    MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
-    MD_CHK( mbedtls_md_finish( ctx, output ) );
-
-    /* Done, get ready for next time */
-    MD_CHK( mbedtls_md_hmac_reset( ctx ) );
-
-#undef MD_CHK
-
-cleanup:
-    mbedtls_md_free( &aux );
-    return( ret );
-}
-
-/*
- * Constant-flow memcpy from variable position in buffer.
- * - functionally equivalent to memcpy(dst, src + offset_secret, len)
- * - but with execution flow independent from the value of offset_secret.
- */
-MBEDTLS_STATIC_TESTABLE void mbedtls_ssl_cf_memcpy_offset(
-                                   unsigned char *dst,
-                                   const unsigned char *src_base,
-                                   size_t offset_secret,
-                                   size_t offset_min, size_t offset_max,
-                                   size_t len )
-{
-    size_t offset;
-
-    for( offset = offset_min; offset <= offset_max; offset++ )
-    {
-        mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len,
-                                     offset, offset_secret );
-    }
-}
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
-
 int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
                              mbedtls_ssl_transform *transform,
                              mbedtls_record *rec )
@@ -1434,7 +1198,7 @@
              *
              * Afterwards, we know that data + data_len is followed by at
              * least maclen Bytes, which justifies the call to
-             * mbedtls_ssl_safer_memcmp() below.
+             * mbedtls_ct_memcmp() below.
              *
              * Further, we still know that data_len > minlen */
             rec->data_len -= transform->maclen;
@@ -1458,8 +1222,8 @@
                                    transform->maclen );
 
             /* Compare expected MAC with MAC at the end of the record. */
-            if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect,
-                                          transform->maclen ) != 0 )
+            if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect,
+                                              transform->maclen ) != 0 )
             {
                 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
                 return( MBEDTLS_ERR_SSL_INVALID_MAC );
@@ -1520,7 +1284,7 @@
 
         if( auth_done == 1 )
         {
-            const size_t mask = mbedtls_ssl_cf_mask_ge(
+            const size_t mask = mbedtls_ct_size_mask_ge(
                                 rec->data_len,
                                 padlen + 1 );
             correct &= mask;
@@ -1540,7 +1304,7 @@
             }
 #endif
 
-            const size_t mask = mbedtls_ssl_cf_mask_ge(
+            const size_t mask = mbedtls_ct_size_mask_ge(
                                 rec->data_len,
                                 transform->maclen + padlen + 1 );
             correct &= mask;
@@ -1574,18 +1338,18 @@
             /* pad_count += (idx >= padding_idx) &&
                 *              (check[idx] == padlen - 1);
                 */
-            const size_t mask = mbedtls_ssl_cf_mask_ge( idx, padding_idx );
-            const size_t equal = mbedtls_ssl_cf_bool_eq( check[idx],
-                                                            padlen - 1 );
+            const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx );
+            const size_t equal = mbedtls_ct_size_bool_eq( check[idx],
+                                                          padlen - 1 );
             pad_count += mask & equal;
         }
-        correct &= mbedtls_ssl_cf_bool_eq( pad_count, padlen );
+        correct &= mbedtls_ct_size_bool_eq( pad_count, padlen );
 
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
         if( padlen > 0 && correct == 0 )
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
 #endif
-        padlen &= mbedtls_ssl_cf_mask_from_bit( correct );
+        padlen &= mbedtls_ct_size_mask( correct );
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -1649,20 +1413,20 @@
         const size_t max_len = rec->data_len + padlen;
         const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
 
-        ret = mbedtls_ssl_cf_hmac( &transform->md_ctx_dec,
-                                    add_data, add_data_len,
-                                    data, rec->data_len, min_len, max_len,
-                                    mac_expect );
+        ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
+                               add_data, add_data_len,
+                               data, rec->data_len, min_len, max_len,
+                               mac_expect );
         if( ret != 0 )
         {
-            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
             return( ret );
         }
 
-        mbedtls_ssl_cf_memcpy_offset( mac_peer, data,
-                                        rec->data_len,
-                                        min_len, max_len,
-                                        transform->maclen );
+        mbedtls_ct_memcpy_offset( mac_peer, data,
+                                  rec->data_len,
+                                  min_len, max_len,
+                                  transform->maclen );
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
@@ -1670,8 +1434,8 @@
         MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", mac_peer, transform->maclen );
 #endif
 
-        if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
-                                      transform->maclen ) != 0 )
+        if( mbedtls_ct_memcmp( mac_peer, mac_expect,
+                                          transform->maclen ) != 0 )
         {
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
@@ -2560,9 +2324,15 @@
 #endif
         /* Skip writing the record content type to after the encryption,
          * as it may change when using the CID extension. */
-
-        mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
-                           ssl->conf->transport, ssl->out_hdr + 1 );
+        int minor_ver = ssl->minor_ver;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+        /* TLS 1.3 still uses the TLS 1.2 version identifier
+         * for backwards compatibility. */
+        if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+            minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+        mbedtls_ssl_write_version( ssl->major_ver, minor_ver,
+                                   ssl->conf->transport, ssl->out_hdr + 1 );
 
         memcpy( ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN );
         MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
@@ -2577,7 +2347,7 @@
             rec.data_offset = ssl->out_msg - rec.buf;
 
             memcpy( &rec.ctr[0], ssl->out_ctr, sizeof( rec.ctr ) );
-            mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+            mbedtls_ssl_write_version( ssl->major_ver, minor_ver,
                                        ssl->conf->transport, rec.ver );
             rec.type = ssl->out_msgtype;
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 881b1fd..5e2d152 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -34,6 +34,8 @@
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -196,7 +198,7 @@
         /* Check verify-data in constant-time. The length OTOH is no secret */
         if( len    != 1 + ssl->verify_data_len ||
             buf[0] !=     ssl->verify_data_len ||
-            mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
+            mbedtls_ct_memcmp( buf + 1, ssl->peer_verify_data,
                           ssl->verify_data_len ) != 0 )
         {
             MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -3569,16 +3571,7 @@
     diff |= peer_pms[1] ^ ver[1];
 
     /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
-    /* MSVC has a warning about unary minus on unsigned, but this is
-     * well-defined and precisely what we want to do here */
-#if defined(_MSC_VER)
-#pragma warning( push )
-#pragma warning( disable : 4146 )
-#endif
-    mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
+    mask = mbedtls_ct_uint_mask( diff );
 
     /*
      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
@@ -3661,7 +3654,7 @@
         /* Identity is not a big secret since clients send it in the clear,
          * but treat it carefully anyway, just in case */
         if( n != ssl->conf->psk_identity_len ||
-            mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+            mbedtls_ct_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
         {
             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
         }
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index d604f38..b07d07a 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -39,6 +39,7 @@
 #include "mbedtls/error.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/version.h"
+#include "mbedtls/constant_time.h"
 
 #include <string.h>
 
@@ -2885,7 +2886,7 @@
         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
     }
 
-    if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+    if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
                       buf, hash_len ) != 0 )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
@@ -5551,8 +5552,13 @@
     psa_destroy_key( handshake->ecdh_psa_privkey );
 #endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
 
-    mbedtls_platform_zeroize( handshake,
-                              sizeof( mbedtls_ssl_handshake_params ) );
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    mbedtls_ssl_transform_free( handshake->transform_handshake );
+    mbedtls_ssl_transform_free( handshake->transform_earlydata );
+    mbedtls_free( handshake->transform_earlydata );
+    mbedtls_free( handshake->transform_handshake );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
     /* If the buffers are too big - reallocate. Because of the way Mbed TLS
@@ -5563,12 +5569,9 @@
                                     mbedtls_ssl_get_output_buflen( ssl ) );
 #endif
 
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
-    mbedtls_free( handshake->transform_earlydata );
-    mbedtls_free( handshake->transform_handshake );
-    handshake->transform_earlydata = NULL;
-    handshake->transform_handshake = NULL;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+    /* mbedtls_platform_zeroize MUST be last one in this function */
+    mbedtls_platform_zeroize( handshake,
+                              sizeof( mbedtls_ssl_handshake_params ) );
 }
 
 void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@@ -6368,6 +6371,12 @@
     MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512,
 #endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP521R1_ENABLED */
 #endif /* MBEDTLS_ECDSA_C */
+
+    /* RSA algorithms */
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA256,
+#endif
+
     MBEDTLS_TLS13_SIG_NONE
 };
 
@@ -6381,6 +6390,12 @@
     MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384,
 #endif /* MBEDTLS_SHA512_C && MBEDTLS_ECP_DP_SECP384R1_ENABLED */
 #endif /* MBEDTLS_ECDSA_C */
+
+    /* RSA algorithms */
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA256,
+#endif
+
     MBEDTLS_TLS13_SIG_NONE
 };
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index 9c88484..d848415 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -798,6 +798,14 @@
 
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    /* Write server name extension */
+    ret = mbedtls_ssl_write_hostname_ext( ssl, p, end, &output_len );
+    if( ret != 0 )
+        return( ret );
+    p += output_len;
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
     /* Add more extensions here */
 
     /* Write the length of the list of extensions. */
@@ -1582,7 +1590,12 @@
  */
 static int ssl_tls1_3_process_certificate_verify( mbedtls_ssl_context *ssl )
 {
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    int ret;
+
+    ret = mbedtls_ssl_tls13_process_certificate_verify( ssl );
+    if( ret != 0 )
+        return( ret );
+
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_SERVER_FINISHED );
     return( 0 );
 }
@@ -1592,27 +1605,13 @@
  */
 static int ssl_tls1_3_process_server_finished( mbedtls_ssl_context *ssl )
 {
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
-    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE );
-    return( 0 );
-}
+    int ret;
 
-/*
- * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
- */
-static int ssl_tls1_3_write_client_certificate( mbedtls_ssl_context *ssl )
-{
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
-    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY );
-    return( 0 );
-}
+    ret = mbedtls_ssl_tls13_process_finished_message( ssl );
+    if( ret != 0 )
+        return( ret );
 
-/*
- * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
- */
-static int ssl_tls1_3_write_client_certificate_verify( mbedtls_ssl_context *ssl )
-{
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_handshake );
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CLIENT_FINISHED );
     return( 0 );
 }
@@ -1620,9 +1619,14 @@
 /*
  * Handler for MBEDTLS_SSL_CLIENT_FINISHED
  */
-static int ssl_tls1_3_write_client_finished( mbedtls_ssl_context *ssl )
+static int ssl_tls13_write_client_finished( mbedtls_ssl_context *ssl )
 {
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    int ret;
+
+    ret = mbedtls_ssl_tls13_write_finished_message( ssl );
+    if( ret != 0 )
+        return( ret );
+
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_FLUSH_BUFFERS );
     return( 0 );
 }
@@ -1632,7 +1636,7 @@
  */
 static int ssl_tls1_3_flush_buffers( mbedtls_ssl_context *ssl )
 {
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
     mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP );
     return( 0 );
 }
@@ -1642,9 +1646,16 @@
  */
 static int ssl_tls1_3_handshake_wrapup( mbedtls_ssl_context *ssl )
 {
-    ((void) ssl);
-    MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) );
-    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for inbound traffic" ) );
+    mbedtls_ssl_set_inbound_transform ( ssl, ssl->transform_application );
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Switch to application keys for outbound traffic" ) );
+    mbedtls_ssl_set_outbound_transform( ssl, ssl->transform_application );
+
+    mbedtls_ssl_tls13_handshake_wrapup( ssl );
+
+    mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_HANDSHAKE_OVER );
+    return( 0 );
 }
 
 int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl )
@@ -1690,16 +1701,8 @@
             ret = ssl_tls1_3_process_server_finished( ssl );
             break;
 
-        case MBEDTLS_SSL_CLIENT_CERTIFICATE:
-            ret = ssl_tls1_3_write_client_certificate( ssl );
-            break;
-
-        case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
-            ret = ssl_tls1_3_write_client_certificate_verify( ssl );
-            break;
-
         case MBEDTLS_SSL_CLIENT_FINISHED:
-            ret = ssl_tls1_3_write_client_finished( ssl );
+            ret = ssl_tls13_write_client_finished( ssl );
             break;
 
         case MBEDTLS_SSL_FLUSH_BUFFERS:
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index c8601ce..2dd5c50 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -23,14 +23,17 @@
 
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
 
+#include <string.h>
+
 #include "mbedtls/error.h"
 #include "mbedtls/debug.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/constant_time.h"
+#include <string.h>
 
 #include "ssl_misc.h"
-#include <mbedtls/debug.h>
-#include <mbedtls/oid.h>
-#include <mbedtls/platform.h>
-
+#include "ssl_tls13_keys.h"
 
 int mbedtls_ssl_tls1_3_fetch_handshake_msg( mbedtls_ssl_context *ssl,
                                             unsigned hs_type,
@@ -217,8 +220,325 @@
     return( 0 );
 }
 
+/*
+ * STATE HANDLING: Read CertificateVerify
+ */
+/* Macro to express the maximum length of the verify structure.
+ *
+ * The structure is computed per TLS 1.3 specification as:
+ *   - 64 bytes of octet 32,
+ *   - 33 bytes for the context string
+ *        (which is either "TLS 1.3, client CertificateVerify"
+ *         or "TLS 1.3, server CertificateVerify"),
+ *   - 1 byte for the octet 0x0, which serves as a separator,
+ *   - 32 or 48 bytes for the Transcript-Hash(Handshake Context, Certificate)
+ *     (depending on the size of the transcript_hash)
+ *
+ * This results in a total size of
+ * - 130 bytes for a SHA256-based transcript hash, or
+ *   (64 + 33 + 1 + 32 bytes)
+ * - 146 bytes for a SHA384-based transcript hash.
+ *   (64 + 33 + 1 + 48 bytes)
+ *
+ */
+#define SSL_VERIFY_STRUCT_MAX_SIZE  ( 64 +                          \
+                                      33 +                          \
+                                       1 +                          \
+                                      MBEDTLS_TLS1_3_MD_MAX_SIZE    \
+                                    )
+
+/*
+ * The ssl_tls13_create_verify_structure() creates the verify structure.
+ * As input, it requires the transcript hash.
+ *
+ * The caller has to ensure that the buffer has size at least
+ * SSL_VERIFY_STRUCT_MAX_SIZE bytes.
+ */
+static void ssl_tls13_create_verify_structure( const unsigned char *transcript_hash,
+                                               size_t transcript_hash_len,
+                                               unsigned char *verify_buffer,
+                                               size_t *verify_buffer_len,
+                                               int from )
+{
+    size_t idx;
+
+    /* RFC 8446, Section 4.4.3:
+     *
+     * The digital signature [in the CertificateVerify message] is then
+     * computed over the concatenation of:
+     * -  A string that consists of octet 32 (0x20) repeated 64 times
+     * -  The context string
+     * -  A single 0 byte which serves as the separator
+     * -  The content to be signed
+     */
+    memset( verify_buffer, 0x20, 64 );
+    idx = 64;
+
+    if( from == MBEDTLS_SSL_IS_CLIENT )
+    {
+        memcpy( verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( client_cv ) );
+        idx += MBEDTLS_SSL_TLS1_3_LBL_LEN( client_cv );
+    }
+    else
+    { /* from == MBEDTLS_SSL_IS_SERVER */
+        memcpy( verify_buffer + idx, MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( server_cv ) );
+        idx += MBEDTLS_SSL_TLS1_3_LBL_LEN( server_cv );
+    }
+
+    verify_buffer[idx++] = 0x0;
+
+    memcpy( verify_buffer + idx, transcript_hash, transcript_hash_len );
+    idx += transcript_hash_len;
+
+    *verify_buffer_len = idx;
+}
+
+static int ssl_tls13_sig_alg_is_offered( const mbedtls_ssl_context *ssl,
+                                         uint16_t sig_alg )
+{
+    const uint16_t *tls13_sig_alg = ssl->conf->tls13_sig_algs;
+
+    for( ; *tls13_sig_alg != MBEDTLS_TLS13_SIG_NONE ; tls13_sig_alg++ )
+    {
+        if( *tls13_sig_alg == sig_alg )
+            return( 1 );
+    }
+    return( 0 );
+}
+
+static int ssl_tls13_parse_certificate_verify( mbedtls_ssl_context *ssl,
+                                               const unsigned char *buf,
+                                               const unsigned char *end,
+                                               const unsigned char *verify_buffer,
+                                               size_t verify_buffer_len )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    const unsigned char *p = buf;
+    uint16_t algorithm;
+    size_t signature_len;
+    mbedtls_pk_type_t sig_alg;
+    mbedtls_md_type_t md_alg;
+    unsigned char verify_hash[MBEDTLS_MD_MAX_SIZE];
+    size_t verify_hash_len;
+
+    void const *opts_ptr = NULL;
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    mbedtls_pk_rsassa_pss_options opts;
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+
+    /*
+     * struct {
+     *     SignatureScheme algorithm;
+     *     opaque signature<0..2^16-1>;
+     * } CertificateVerify;
+     */
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    algorithm = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+
+    /* RFC 8446 section 4.4.3
+     *
+     * If the CertificateVerify message is sent by a server, the signature algorithm
+     * MUST be one offered in the client's "signature_algorithms" extension unless
+     * no valid certificate chain can be produced without unsupported algorithms
+     *
+     * RFC 8446 section 4.4.2.2
+     *
+     * If the client cannot construct an acceptable chain using the provided
+     * certificates and decides to abort the handshake, then it MUST abort the handshake
+     * with an appropriate certificate-related alert (by default, "unsupported_certificate").
+     *
+     * Check if algorithm is an offered signature algorithm.
+     */
+    if( ! ssl_tls13_sig_alg_is_offered( ssl, algorithm ) )
+    {
+        /* algorithm not in offered signature algorithms list */
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Received signature algorithm(%04x) is not "
+                                    "offered.",
+                                    ( unsigned int ) algorithm ) );
+        goto error;
+    }
+
+    /* We currently only support ECDSA-based signatures */
+    switch( algorithm )
+    {
+        case MBEDTLS_TLS13_SIG_ECDSA_SECP256R1_SHA256:
+            md_alg = MBEDTLS_MD_SHA256;
+            sig_alg = MBEDTLS_PK_ECDSA;
+            break;
+        case MBEDTLS_TLS13_SIG_ECDSA_SECP384R1_SHA384:
+            md_alg = MBEDTLS_MD_SHA384;
+            sig_alg = MBEDTLS_PK_ECDSA;
+            break;
+        case MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512:
+            md_alg = MBEDTLS_MD_SHA512;
+            sig_alg = MBEDTLS_PK_ECDSA;
+            break;
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+        case MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA256:
+            MBEDTLS_SSL_DEBUG_MSG( 4, ( "Certificate Verify: using RSA" ) );
+            md_alg = MBEDTLS_MD_SHA256;
+            sig_alg = MBEDTLS_PK_RSASSA_PSS;
+            break;
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+        default:
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Certificate Verify: Unknown signature algorithm." ) );
+            goto error;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate Verify: Signature algorithm ( %04x )",
+                                ( unsigned int ) algorithm ) );
+
+    /*
+     * Check the certificate's key type matches the signature alg
+     */
+    if( !mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, sig_alg ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "signature algorithm doesn't match cert key" ) );
+        goto error;
+    }
+
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 );
+    signature_len = MBEDTLS_GET_UINT16_BE( p, 0 );
+    p += 2;
+    MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, signature_len );
+
+    /* Hash verify buffer with indicated hash function */
+    switch( md_alg )
+    {
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_MD_SHA256:
+            verify_hash_len = 32;
+            ret = mbedtls_sha256( verify_buffer, verify_buffer_len, verify_hash, 0 );
+            break;
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA384_C)
+        case MBEDTLS_MD_SHA384:
+            verify_hash_len = 48;
+            ret = mbedtls_sha512( verify_buffer, verify_buffer_len, verify_hash, 1 );
+            break;
+#endif /* MBEDTLS_SHA384_C */
+
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_MD_SHA512:
+            verify_hash_len = 64;
+            ret = mbedtls_sha512( verify_buffer, verify_buffer_len, verify_hash, 0 );
+            break;
+#endif /* MBEDTLS_SHA512_C */
+
+        default:
+            ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
+            break;
+    }
+
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "hash computation error", ret );
+        goto error;
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "verify hash", verify_hash, verify_hash_len );
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    if( sig_alg == MBEDTLS_PK_RSASSA_PSS )
+    {
+        const mbedtls_md_info_t* md_info;
+        opts.mgf1_hash_id = md_alg;
+        if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
+        {
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+        opts.expected_salt_len = mbedtls_md_get_size( md_info );
+        opts_ptr = (const void*) &opts;
+    }
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+
+    if( ( ret = mbedtls_pk_verify_ext( sig_alg, opts_ptr,
+                                       &ssl->session_negotiate->peer_cert->pk,
+                                       md_alg, verify_hash, verify_hash_len,
+                                       p, signature_len ) ) == 0 )
+    {
+        return( 0 );
+    }
+    MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify_ext", ret );
+
+error:
+    /* RFC 8446 section 4.4.3
+     *
+     * If the verification fails, the receiver MUST terminate the handshake
+     * with a "decrypt_error" alert.
+    */
+    MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
+                                  MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+
+}
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
+int mbedtls_ssl_tls13_process_certificate_verify( mbedtls_ssl_context *ssl )
+{
+
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char verify_buffer[SSL_VERIFY_STRUCT_MAX_SIZE];
+    size_t verify_buffer_len;
+    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+    size_t transcript_len;
+    unsigned char *buf;
+    size_t buf_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
+
+    MBEDTLS_SSL_PROC_CHK(
+        mbedtls_ssl_tls1_3_fetch_handshake_msg( ssl,
+                MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, &buf, &buf_len ) );
+
+    /* Need to calculate the hash of the transcript first
+     * before reading the message since otherwise it gets
+     * included in the transcript
+     */
+    ret = mbedtls_ssl_get_handshake_transcript( ssl,
+                            ssl->handshake->ciphersuite_info->mac,
+                            transcript, sizeof( transcript ),
+                            &transcript_len );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_PEND_FATAL_ALERT(
+            MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR,
+            MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "handshake hash", transcript, transcript_len );
+
+    /* Create verify structure */
+    ssl_tls13_create_verify_structure( transcript,
+                                       transcript_len,
+                                       verify_buffer,
+                                       &verify_buffer_len,
+                                       ( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ?
+                                         MBEDTLS_SSL_IS_SERVER :
+                                         MBEDTLS_SSL_IS_CLIENT );
+
+    /* Process the message contents */
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_certificate_verify( ssl, buf,
+                            buf + buf_len, verify_buffer, verify_buffer_len ) );
+
+    mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( ssl,
+                        MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, buf, buf_len );
+
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
+    MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_process_certificate_verify", ret );
+    return( ret );
+#else
+    ((void) ssl);
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+}
+
 /*
  *
  * STATE HANDLING: Incoming Certificate, client-side only currently.
@@ -552,6 +872,282 @@
     return( ret );
 }
 
+/*
+ *
+ * STATE HANDLING: Incoming Finished message.
+ */
+/*
+ * Implementation
+ */
+
+static int ssl_tls13_preprocess_finished_message( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    ret = mbedtls_ssl_tls13_calculate_verify_data( ssl,
+                    ssl->handshake->state_local.finished_in.digest,
+                    sizeof( ssl->handshake->state_local.finished_in.digest ),
+                    &ssl->handshake->state_local.finished_in.digest_len,
+                    ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ?
+                        MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_calculate_verify_data", ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+static int ssl_tls13_parse_finished_message( mbedtls_ssl_context *ssl,
+                                             const unsigned char *buf,
+                                             const unsigned char *end )
+{
+    /*
+     * struct {
+     *     opaque verify_data[Hash.length];
+     * } Finished;
+     */
+    const unsigned char *expected_verify_data =
+        ssl->handshake->state_local.finished_in.digest;
+    size_t expected_verify_data_len =
+        ssl->handshake->state_local.finished_in.digest_len;
+    /* Structural validation */
+    if( (size_t)( end - buf ) != expected_verify_data_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
+                                      MBEDTLS_ERR_SSL_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_DECODE_ERROR );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "verify_data (self-computed):",
+                           expected_verify_data,
+                           expected_verify_data_len );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "verify_data (received message):", buf,
+                           expected_verify_data_len );
+
+    /* Semantic validation */
+    if( mbedtls_ct_memcmp( buf,
+                           expected_verify_data,
+                           expected_verify_data_len ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+
+        MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
+                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_CLI_C)
+static int ssl_tls13_postprocess_server_finished_message( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_ssl_key_set traffic_keys;
+    mbedtls_ssl_transform *transform_application = NULL;
+
+    ret = mbedtls_ssl_tls13_key_schedule_stage_application( ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+           "mbedtls_ssl_tls13_key_schedule_stage_application", ret );
+        goto cleanup;
+    }
+
+    ret = mbedtls_ssl_tls13_generate_application_keys( ssl, &traffic_keys );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+            "mbedtls_ssl_tls13_generate_application_keys", ret );
+        goto cleanup;
+    }
+
+    transform_application =
+        mbedtls_calloc( 1, sizeof( mbedtls_ssl_transform ) );
+    if( transform_application == NULL )
+    {
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    ret = mbedtls_ssl_tls13_populate_transform(
+                                    transform_application,
+                                    ssl->conf->endpoint,
+                                    ssl->session_negotiate->ciphersuite,
+                                    &traffic_keys,
+                                    ssl );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls13_populate_transform", ret );
+        goto cleanup;
+    }
+
+    ssl->transform_application = transform_application;
+
+cleanup:
+
+    mbedtls_platform_zeroize( &traffic_keys, sizeof( traffic_keys ) );
+    if( ret != 0 )
+    {
+        mbedtls_free( transform_application );
+        MBEDTLS_SSL_PEND_FATAL_ALERT(
+                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
+                MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE );
+    }
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_CLI_C */
+
+static int ssl_tls13_postprocess_finished_message( mbedtls_ssl_context *ssl )
+{
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        return( ssl_tls13_postprocess_server_finished_message( ssl ) );
+    }
+#else
+    ((void) ssl);
+#endif /* MBEDTLS_SSL_CLI_C */
+
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+int mbedtls_ssl_tls13_process_finished_message( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char *buf;
+    size_t buflen;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished message" ) );
+
+    /* Preprocessing step: Compute handshake digest */
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_preprocess_finished_message( ssl ) );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls1_3_fetch_handshake_msg( ssl,
+                                              MBEDTLS_SSL_HS_FINISHED,
+                                              &buf, &buflen ) );
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_parse_finished_message( ssl, buf, buf + buflen ) );
+    mbedtls_ssl_tls1_3_add_hs_msg_to_checksum(
+        ssl, MBEDTLS_SSL_HS_FINISHED, buf, buflen );
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_finished_message( ssl ) );
+
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished message" ) );
+    return( ret );
+}
+
+/*
+ *
+ * STATE HANDLING: Write and send Finished message.
+ *
+ */
+/*
+ * Implement
+ */
+
+static int ssl_tls13_prepare_finished_message( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    /* Compute transcript of handshake up to now. */
+    ret = mbedtls_ssl_tls13_calculate_verify_data( ssl,
+                    ssl->handshake->state_local.finished_out.digest,
+                    sizeof( ssl->handshake->state_local.finished_out.digest ),
+                    &ssl->handshake->state_local.finished_out.digest_len,
+                    ssl->conf->endpoint );
+
+    if( ret != 0 )
+    {
+         MBEDTLS_SSL_DEBUG_RET( 1, "calculate_verify_data failed", ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+static int ssl_tls13_finalize_finished_message( mbedtls_ssl_context *ssl )
+{
+    // TODO: Add back resumption keys calculation after MVP.
+    ((void) ssl);
+
+    return( 0 );
+}
+
+static int ssl_tls13_write_finished_message_body( mbedtls_ssl_context *ssl,
+                                                  unsigned char *buf,
+                                                  unsigned char *end,
+                                                  size_t *olen )
+{
+    size_t verify_data_len = ssl->handshake->state_local.finished_out.digest_len;
+    /*
+     * struct {
+     *     opaque verify_data[Hash.length];
+     * } Finished;
+     */
+    MBEDTLS_SSL_CHK_BUF_PTR( buf, end, verify_data_len );
+
+    memcpy( buf, ssl->handshake->state_local.finished_out.digest,
+            verify_data_len );
+
+    *olen = verify_data_len;
+    return( 0 );
+}
+
+/* Main entry point: orchestrates the other functions */
+int mbedtls_ssl_tls13_write_finished_message( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char *buf;
+    size_t buf_len, msg_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished message" ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_prepare_finished_message( ssl ) );
+
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_start_handshake_msg( ssl,
+                              MBEDTLS_SSL_HS_FINISHED, &buf, &buf_len ) );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_finished_message_body(
+                              ssl, buf, buf + buf_len, &msg_len ) );
+
+    mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( ssl, MBEDTLS_SSL_HS_FINISHED,
+                                               buf, msg_len );
+
+    MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_finished_message( ssl ) );
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_finish_handshake_msg( ssl,
+                                              buf_len, msg_len ) );
+    MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_flush_output( ssl ) );
+
+cleanup:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished message" ) );
+    return( ret );
+}
+
+void mbedtls_ssl_tls13_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
+
+    /*
+     * Free the previous session and switch to the current one.
+     */
+    if( ssl->session )
+    {
+        mbedtls_ssl_session_free( ssl->session );
+        mbedtls_free( ssl->session );
+    }
+    ssl->session = ssl->session_negotiate;
+    ssl->session_negotiate = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #endif /* MBEDTLS_SSL_TLS_C */
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index 96f5310..3ca28d5 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -564,6 +564,35 @@
     return( 0 );
 }
 
+int mbedtls_ssl_tls13_key_schedule_stage_application( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+    mbedtls_md_type_t const md_type = handshake->ciphersuite_info->mac;
+#if defined(MBEDTLS_DEBUG_C)
+    mbedtls_md_info_t const * const md_info = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md_info );
+#endif /* MBEDTLS_DEBUG_C */
+
+    /*
+     * Compute MasterSecret
+     */
+    ret = mbedtls_ssl_tls1_3_evolve_secret( md_type,
+                    handshake->tls1_3_master_secrets.handshake,
+                    NULL, 0,
+                    handshake->tls1_3_master_secrets.app );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_evolve_secret", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "Master secret",
+             handshake->tls1_3_master_secrets.app, md_size );
+
+    return( 0 );
+}
+
 static int ssl_tls1_3_calc_finished_core( mbedtls_md_type_t md_type,
                                           unsigned char const *base_key,
                                           unsigned char const *transcript,
@@ -614,6 +643,57 @@
     return( ret );
 }
 
+int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context* ssl,
+                                             unsigned char* dst,
+                                             size_t dst_len,
+                                             size_t *actual_len,
+                                             int from )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+    size_t transcript_len;
+
+    unsigned char const *base_key = NULL;
+
+    mbedtls_md_type_t const md_type = ssl->handshake->ciphersuite_info->mac;
+    const mbedtls_md_info_t* const md = mbedtls_md_info_from_type( md_type );
+    size_t const md_size = mbedtls_md_get_size( md );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_tls13_calculate_verify_data" ) );
+
+    if( dst_len < md_size )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+    ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type,
+                                                transcript, sizeof( transcript ),
+                                                &transcript_len );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_handshake_transcript", ret );
+        goto exit;
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 4, "handshake hash", transcript, transcript_len );
+
+    if( from == MBEDTLS_SSL_IS_CLIENT )
+        base_key = ssl->handshake->tls13_hs_secrets.client_handshake_traffic_secret;
+    else
+        base_key = ssl->handshake->tls13_hs_secrets.server_handshake_traffic_secret;
+
+    ret = ssl_tls1_3_calc_finished_core( md_type, base_key, transcript, dst );
+    if( ret != 0 )
+        goto exit;
+    *actual_len = md_size;
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "verify_data for finished message", dst, md_size );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_tls13_calculate_verify_data" ) );
+
+exit:
+
+    mbedtls_platform_zeroize( transcript, sizeof( transcript ) );
+    return( ret );
+}
+
 int mbedtls_ssl_tls1_3_create_psk_binder( mbedtls_ssl_context *ssl,
                                const mbedtls_md_type_t md_type,
                                unsigned char const *psk, size_t psk_len,
@@ -1028,4 +1108,125 @@
     return( 0 );
 }
 
+/* Generate application traffic keys since any records following a 1-RTT Finished message
+ * MUST be encrypted under the application traffic key.
+ */
+int mbedtls_ssl_tls13_generate_application_keys(
+                                        mbedtls_ssl_context *ssl,
+                                        mbedtls_ssl_key_set *traffic_keys )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+    /* Address at which to store the application secrets */
+    mbedtls_ssl_tls1_3_application_secrets * const app_secrets =
+        &ssl->session_negotiate->app_secrets;
+
+    /* Holding the transcript up to and including the ServerFinished */
+    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
+    size_t transcript_len;
+
+    /* Variables relating to the hash for the chosen ciphersuite. */
+    mbedtls_md_type_t md_type;
+    mbedtls_md_info_t const *md_info;
+    size_t md_size;
+
+    /* Variables relating to the cipher for the chosen ciphersuite. */
+    mbedtls_cipher_info_t const *cipher_info;
+    size_t keylen, ivlen;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive application traffic keys" ) );
+
+    /* Extract basic information about hash and ciphersuite */
+
+    cipher_info = mbedtls_cipher_info_from_type(
+                                  handshake->ciphersuite_info->cipher );
+    keylen = cipher_info->key_bitlen / 8;
+    ivlen = cipher_info->iv_size;
+
+    md_type = handshake->ciphersuite_info->mac;
+    md_info = mbedtls_md_info_from_type( md_type );
+    md_size = mbedtls_md_get_size( md_info );
+
+    /* Compute current handshake transcript. It's the caller's responsiblity
+     * to call this at the right time, that is, after the ServerFinished. */
+
+    ret = mbedtls_ssl_get_handshake_transcript( ssl, md_type,
+                                      transcript, sizeof( transcript ),
+                                      &transcript_len );
+    if( ret != 0 )
+        goto cleanup;
+
+    /* Compute application secrets from master secret and transcript hash. */
+
+    ret = mbedtls_ssl_tls1_3_derive_application_secrets( md_type,
+                                   handshake->tls1_3_master_secrets.app,
+                                   transcript, transcript_len,
+                                   app_secrets );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1,
+                     "mbedtls_ssl_tls1_3_derive_application_secrets", ret );
+        goto cleanup;
+    }
+
+    /* Derive first epoch of IV + Key for application traffic. */
+
+    ret = mbedtls_ssl_tls1_3_make_traffic_keys( md_type,
+                             app_secrets->client_application_traffic_secret_N,
+                             app_secrets->server_application_traffic_secret_N,
+                             md_size, keylen, ivlen, traffic_keys );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_tls1_3_make_traffic_keys", ret );
+        goto cleanup;
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "Client application traffic secret",
+                           app_secrets->client_application_traffic_secret_N,
+                           md_size );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "Server application traffic secret",
+                           app_secrets->server_application_traffic_secret_N,
+                           md_size );
+
+    /*
+     * Export client/server application traffic secret 0
+     */
+    if( ssl->f_export_keys != NULL )
+    {
+        ssl->f_export_keys( ssl->p_export_keys,
+                MBEDTLS_SSL_KEY_EXPORT_TLS13_CLIENT_APPLICATION_TRAFFIC_SECRET,
+                app_secrets->client_application_traffic_secret_N, md_size,
+                handshake->randbytes + 32,
+                handshake->randbytes,
+                MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
+                                            a new constant for TLS 1.3! */ );
+
+        ssl->f_export_keys( ssl->p_export_keys,
+                MBEDTLS_SSL_KEY_EXPORT_TLS13_SERVER_APPLICATION_TRAFFIC_SECRET,
+                app_secrets->server_application_traffic_secret_N, md_size,
+                handshake->randbytes + 32,
+                handshake->randbytes,
+                MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
+                                            a new constant for TLS 1.3! */ );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "client application_write_key:",
+                              traffic_keys->client_write_key, keylen );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "server application write key",
+                              traffic_keys->server_write_key, keylen );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "client application write IV",
+                              traffic_keys->client_write_iv, ivlen );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "server application write IV",
+                              traffic_keys->server_write_iv, ivlen );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive application traffic keys" ) );
+
+ cleanup:
+
+    mbedtls_platform_zeroize( transcript, sizeof( transcript ) );
+    return( ret );
+}
+
 #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index 384f433..d598448 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -22,25 +22,27 @@
 /* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at
  * the point of use. See e.g. the definition of mbedtls_ssl_tls1_3_labels_union
  * below. */
-#define MBEDTLS_SSL_TLS1_3_LABEL_LIST                               \
-    MBEDTLS_SSL_TLS1_3_LABEL( finished    , "finished"     ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( resumption  , "resumption"   ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd"  ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( exporter    , "exporter"     ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( key         , "key"          ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( iv          , "iv"           ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic" ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic" ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic"  ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic" ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic" ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic"  ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master" ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( res_master  , "res master"   ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( exp_master  , "exp master"   ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( ext_binder  , "ext binder"   ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( res_binder  , "res binder"   ) \
-    MBEDTLS_SSL_TLS1_3_LABEL( derived     , "derived"      )
+#define MBEDTLS_SSL_TLS1_3_LABEL_LIST                                             \
+    MBEDTLS_SSL_TLS1_3_LABEL( finished    , "finished"                          ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( resumption  , "resumption"                        ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd"                       ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( exporter    , "exporter"                          ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( key         , "key"                               ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( iv          , "iv"                                ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic"                      ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic"                      ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic"                       ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic"                      ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic"                      ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic"                       ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master"                      ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( res_master  , "res master"                        ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( exp_master  , "exp master"                        ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( ext_binder  , "ext binder"                        ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( res_binder  , "res binder"                        ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( derived     , "derived"                           ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( client_cv   , "TLS 1.3, client CertificateVerify" ) \
+    MBEDTLS_SSL_TLS1_3_LABEL( server_cv   , "TLS 1.3, server CertificateVerify" )
 
 #define MBEDTLS_SSL_TLS1_3_LABEL( name, string )       \
     const unsigned char name    [ sizeof(string) - 1 ];
@@ -57,9 +59,12 @@
 
 extern const struct mbedtls_ssl_tls1_3_labels_struct mbedtls_ssl_tls1_3_labels;
 
+#define MBEDTLS_SSL_TLS1_3_LBL_LEN( LABEL )  \
+    sizeof(mbedtls_ssl_tls1_3_labels.LABEL)
+
 #define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( LABEL )  \
     mbedtls_ssl_tls1_3_labels.LABEL,              \
-    sizeof(mbedtls_ssl_tls1_3_labels.LABEL)
+    MBEDTLS_SSL_TLS1_3_LBL_LEN( LABEL )
 
 #define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN  \
     sizeof( union mbedtls_ssl_tls1_3_labels_union )
@@ -565,4 +570,65 @@
 int mbedtls_ssl_tls13_generate_handshake_keys( mbedtls_ssl_context *ssl,
                                                mbedtls_ssl_key_set *traffic_keys );
 
+/**
+ * \brief Transition into application stage of TLS 1.3 key schedule.
+ *
+ *        The TLS 1.3 key schedule can be viewed as a simple state machine
+ *        with states Initial -> Early -> Handshake -> Application, and
+ *        this function represents the Handshake -> Application transition.
+ *
+ *        In the handshake stage, mbedtls_ssl_tls13_generate_application_keys()
+ *        can be used to derive the handshake traffic keys.
+ *
+ * \param ssl  The SSL context to operate on. This must be in key schedule
+ *             stage \c Handshake.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_key_schedule_stage_application( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Compute TLS 1.3 application traffic keys.
+ *
+ * \param ssl  The SSL context to operate on. This must be in
+ *             key schedule stage \c Application, see
+ *             mbedtls_ssl_tls13_key_schedule_stage_application().
+ * \param traffic_keys The address at which to store the application traffic key
+ *                     keys. This must be writable but may be uninitialized.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_generate_application_keys(
+    mbedtls_ssl_context* ssl, mbedtls_ssl_key_set *traffic_keys );
+
+/**
+ * \brief Calculate the verify_data value for the client or server TLS 1.3
+ * Finished message.
+ *
+ * \param ssl  The SSL context to operate on. This must be in
+ *             key schedule stage \c Handshake, see
+ *             mbedtls_ssl_tls13_key_schedule_stage_application().
+ * \param dst        The address at which to write the verify_data value.
+ * \param dst_len    The size of \p dst in bytes.
+ * \param actual_len The address at which to store the amount of data
+ *                   actually written to \p dst upon success.
+ * \param which      The message to calculate the `verify_data` for:
+ *                   - #MBEDTLS_SSL_IS_CLIENT for the Client's Finished message
+ *                   - #MBEDTLS_SSL_IS_SERVER for the Server's Finished message
+ *
+ * \note       Both client and server call this function twice, once to
+ *             generate their own Finished message, and once to verify the
+ *             peer's Finished message.
+
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_calculate_verify_data( mbedtls_ssl_context *ssl,
+                                             unsigned char *dst,
+                                             size_t dst_len,
+                                             size_t *actual_len,
+                                             int which );
+
 #endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 29bda7f..204b975 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -21,6 +21,10 @@
 
 #include "ssl_test_lib.h"
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "test/psa_crypto_helpers.h"
+#endif
+
 #if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
 int main( void )
 {
@@ -1530,6 +1534,10 @@
             {
                 sig_alg_list[i++] = MBEDTLS_TLS13_SIG_ECDSA_SECP521R1_SHA512;
             }
+            else if( strcmp( q, "rsa_pss_rsae_sha256" ) == 0 )
+            {
+                sig_alg_list[i++] = MBEDTLS_TLS13_SIG_RSA_PSS_RSAE_SHA256;
+            }
             else
             {
                 mbedtls_printf( "unknown signature algorithm %s\n", q );
@@ -1537,6 +1545,7 @@
                 mbedtls_printf( "ecdsa_secp256r1_sha256 " );
                 mbedtls_printf( "ecdsa_secp384r1_sha384 " );
                 mbedtls_printf( "ecdsa_secp521r1_sha512 " );
+                mbedtls_printf( "rsa_pss_rsae_sha256 " );
                 mbedtls_printf( "\n" );
                 goto exit;
             }
@@ -3015,6 +3024,19 @@
 
     mbedtls_net_free( &server_fd );
 
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
+    mbedtls_ssl_session_free( &saved_session );
+
+    if( session_data != NULL )
+        mbedtls_platform_zeroize( session_data, session_data_len );
+    mbedtls_free( session_data );
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( context_buf != NULL )
+        mbedtls_platform_zeroize( context_buf, context_buf_len );
+    mbedtls_free( context_buf );
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_free( &clicert );
     mbedtls_x509_crt_free( &cacert );
@@ -3045,23 +3067,25 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
           MBEDTLS_USE_PSA_CRYPTO */
 
-    mbedtls_ssl_session_free( &saved_session );
-    mbedtls_ssl_free( &ssl );
-    mbedtls_ssl_config_free( &conf );
-    rng_free( &rng );
-    if( session_data != NULL )
-        mbedtls_platform_zeroize( session_data, session_data_len );
-    mbedtls_free( session_data );
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
-    if( context_buf != NULL )
-        mbedtls_platform_zeroize( context_buf, context_buf_len );
-    mbedtls_free( context_buf );
-#endif
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+    const char* message = mbedtls_test_helper_is_psa_leaking();
+    if( message )
+    {
+        if( ret == 0 )
+            ret = 1;
+        mbedtls_printf( "PSA memory leak detected: %s\n",  message);
+    }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+    /* For builds with MBEDTLS_TEST_USE_PSA_CRYPTO_RNG psa crypto
+     * resources are freed by rng_free(). */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+    !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
     mbedtls_psa_crypto_free( );
 #endif
 
+    rng_free( &rng );
+
 #if defined(MBEDTLS_TEST_HOOKS)
     if( test_hooks_failure_detected( ) )
     {
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 4d785d7..0e6f78b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -65,6 +65,10 @@
 #include <windows.h>
 #endif
 
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "test/psa_crypto_helpers.h"
+#endif
+
 /* Size of memory to be allocated for the heap, when using the library's memory
  * management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */
 #define MEMORY_HEAP_SIZE        120000
@@ -3947,9 +3951,35 @@
     mbedtls_net_free( &client_fd );
     mbedtls_net_free( &listen_fd );
 
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
-    mbedtls_dhm_free( &dhm );
+    mbedtls_ssl_free( &ssl );
+    mbedtls_ssl_config_free( &conf );
+
+#if defined(MBEDTLS_SSL_CACHE_C)
+    mbedtls_ssl_cache_free( &cache );
 #endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    mbedtls_ssl_ticket_free( &ticket_ctx );
+#endif
+#if defined(MBEDTLS_SSL_COOKIE_C)
+    mbedtls_ssl_cookie_free( &cookie_ctx );
+#endif
+
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+    if( context_buf != NULL )
+        mbedtls_platform_zeroize( context_buf, context_buf_len );
+    mbedtls_free( context_buf );
+#endif
+
+#if defined(SNI_OPTION)
+    sni_free( sni_info );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+    ret = psk_free( psk_info );
+    if( ( ret != 0 ) && ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
+        mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
+#endif
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_free( &cacert );
     mbedtls_x509_crt_free( &srvcert );
@@ -3961,6 +3991,11 @@
     psa_destroy_key( key_slot2 );
 #endif
 #endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
+    mbedtls_dhm_free( &dhm );
+#endif
+
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
     for( i = 0; (size_t) i < ssl_async_keys.slots_used; i++ )
     {
@@ -3972,17 +4007,6 @@
         }
     }
 #endif
-#if defined(SNI_OPTION)
-    sni_free( sni_info );
-#endif
-#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
-    ret = psk_free( psk_info );
-    if( ( ret != 0 ) && ( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
-        mbedtls_printf( "Failed to list of opaque PSKs - error was %d\n", ret );
-#endif
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
-    mbedtls_dhm_free( &dhm );
-#endif
 
 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) && \
     defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -4003,32 +4027,27 @@
 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
           MBEDTLS_USE_PSA_CRYPTO */
 
-    mbedtls_ssl_free( &ssl );
-    mbedtls_ssl_config_free( &conf );
-    rng_free( &rng );
-
-#if defined(MBEDTLS_SSL_CACHE_C)
-    mbedtls_ssl_cache_free( &cache );
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-    mbedtls_ssl_ticket_free( &ticket_ctx );
-#endif
-#if defined(MBEDTLS_SSL_COOKIE_C)
-    mbedtls_ssl_cookie_free( &cookie_ctx );
-#endif
-
-    mbedtls_free( buf );
-
-#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
-    if( context_buf != NULL )
-        mbedtls_platform_zeroize( context_buf, context_buf_len );
-    mbedtls_free( context_buf );
-#endif
-
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
+    const char* message = mbedtls_test_helper_is_psa_leaking();
+    if( message )
+    {
+        if( ret == 0 )
+            ret = 1;
+        mbedtls_printf( "PSA memory leak detected: %s\n",  message);
+    }
+#endif
+
+    /* For builds with MBEDTLS_TEST_USE_PSA_CRYPTO_RNG psa crypto
+     * resources are freed by rng_free(). */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+    !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
     mbedtls_psa_crypto_free( );
 #endif
 
+    rng_free( &rng );
+
+    mbedtls_free( buf );
+
 #if defined(MBEDTLS_TEST_HOOKS)
     /* Let test hooks detect errors such as resource leaks.
      * Don't do it in query_config mode, because some test code prints
diff --git a/scripts/mbedtls_dev/test_case.py b/scripts/mbedtls_dev/test_case.py
index d01e143..6a46e42 100644
--- a/scripts/mbedtls_dev/test_case.py
+++ b/scripts/mbedtls_dev/test_case.py
@@ -83,8 +83,6 @@
             out.write('depends_on:' + ':'.join(self.dependencies) + '\n')
         out.write(self.function + ':' + ':'.join(self.arguments) + '\n')
 
-
-
 def write_data_file(filename: str,
                     test_cases: Iterable[TestCase],
                     caller: Optional[str] = None) -> None:
diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h
index 8a8c37e..f5622e2 100644
--- a/tests/include/test/psa_crypto_helpers.h
+++ b/tests/include/test/psa_crypto_helpers.h
@@ -28,7 +28,6 @@
 #include "test/psa_helpers.h"
 
 #include <psa/crypto.h>
-#include <psa_crypto_slot_management.h>
 
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #include "mbedtls/psa_util.h"
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index df0b762..b677587 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2771,6 +2771,26 @@
     unset gdb_disable_aslr
 }
 
+component_test_psa_compliance () {
+    msg "build: make, default config (out-of-box), libmbedcrypto.a only"
+    make -C library libmbedcrypto.a
+
+    msg "unit test: test_psa_compliance.py"
+    ./tests/scripts/test_psa_compliance.py
+}
+
+support_test_psa_compliance () {
+    # psa-compliance-tests only supports CMake >= 3.10.0
+    ver="$(cmake --version)"
+    ver="${ver#cmake version }"
+    ver_major="${ver%%.*}"
+
+    ver="${ver#*.}"
+    ver_minor="${ver%%.*}"
+
+    [ "$ver_major" -eq 3 ] && [ "$ver_minor" -ge 10 ]
+}
+
 component_check_python_files () {
     msg "Lint: Python scripts"
     tests/scripts/check-python-files.sh
diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py
index 39fb210..0d9cb36 100755
--- a/tests/scripts/generate_psa_tests.py
+++ b/tests/scripts/generate_psa_tests.py
@@ -96,7 +96,7 @@
     if _implemented_dependencies is None:
         _implemented_dependencies = \
             read_implemented_dependencies('include/psa/crypto_config.h')
-    if not all(dep.lstrip('!') in _implemented_dependencies
+    if not all((dep.lstrip('!') in _implemented_dependencies or 'PSA_WANT' not in dep)
                for dep in dependencies):
         dependencies.append('DEPENDENCY_NOT_IMPLEMENTED_YET')
 
@@ -155,30 +155,8 @@
     tc.set_arguments([key_type] + list(args))
     return tc
 
-def test_case_for_key_type_invalid_argument(
-        verb: str, key_type: str, bits: int,
-        dependencies: List[str],
-        *args: str,
-        param_descr: str = ''
-) -> test_case.TestCase:
-    """Return one test case exercising a key creation method
-    for an invalid argument when key is public.
-    """
-    hack_dependencies_not_implemented(dependencies)
-    tc = test_case.TestCase()
-    short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
-    adverb = 'not' if dependencies else 'never'
-    if param_descr:
-        adverb = param_descr + ' ' + adverb
-    tc.set_description('PSA {} {} {}-bit invalid argument'
-                       .format(verb, short_key_type, bits))
-    tc.set_function(verb + '_invalid_argument')
-    tc.set_dependencies(dependencies)
-    tc.set_arguments([key_type] + list(args))
-    return tc
-
 class NotSupported:
-    """Generate test cases for when something is not supported or argument is inavlid."""
+    """Generate test cases for when something is not supported."""
 
     def __init__(self, info: Information) -> None:
         self.constructors = info.constructors
@@ -193,13 +171,11 @@
             param: Optional[int] = None,
             param_descr: str = '',
     ) -> Iterator[test_case.TestCase]:
-        """Return test cases exercising key creation when the given type is unsupported
-        or argument is invalid.
+        """Return test cases exercising key creation when the given type is unsupported.
 
         If param is present and not None, emit test cases conditioned on this
         parameter not being supported. If it is absent or None, emit test cases
-        conditioned on the base type not being supported. If key is public emit test
-        case for invalid argument.
+        conditioned on the base type not being supported.
         """
         if kt.name in self.ALWAYS_SUPPORTED:
             # Don't generate test cases for key types that are always supported.
@@ -227,14 +203,9 @@
                 # supported or not depending on implementation capabilities,
                 # only generate the test case once.
                 continue
-            if kt.name.endswith('_PUBLIC_KEY'):
-                yield test_case_for_key_type_invalid_argument(
-                    'generate', kt.expression, bits,
-                    finish_family_dependencies(generate_dependencies, bits),
-                    str(bits),
-                    param_descr=param_descr,
-                )
-            else:
+                # For public key we expect that key generation fails with
+                # INVALID_ARGUMENT. It is handled by KeyGenerate class.
+            if not kt.name.endswith('_PUBLIC_KEY'):
                 yield test_case_for_key_type_not_supported(
                     'generate', kt.expression, bits,
                     finish_family_dependencies(generate_dependencies, bits),
@@ -261,6 +232,79 @@
                 yield from self.test_cases_for_key_type_not_supported(
                     kt, 0, param_descr='curve')
 
+def test_case_for_key_generation(
+        key_type: str, bits: int,
+        dependencies: List[str],
+        *args: str,
+        result: str = ''
+) -> test_case.TestCase:
+    """Return one test case exercising a key generation.
+    """
+    hack_dependencies_not_implemented(dependencies)
+    tc = test_case.TestCase()
+    short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type)
+    tc.set_description('PSA {} {}-bit'
+                       .format(short_key_type, bits))
+    tc.set_dependencies(dependencies)
+    tc.set_function('generate_key')
+    tc.set_arguments([key_type] + list(args) + [result])
+
+    return tc
+
+class KeyGenerate:
+    """Generate positive and negative (invalid argument) test cases for key generation."""
+
+    def __init__(self, info: Information) -> None:
+        self.constructors = info.constructors
+
+    ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR',
+                     'PSA_KEY_TYPE_ECC_PUBLIC_KEY')
+
+    @staticmethod
+    def test_cases_for_key_type_key_generation(
+            kt: crypto_knowledge.KeyType
+    ) -> Iterator[test_case.TestCase]:
+        """Return test cases exercising key generation.
+
+        All key types can be generated except for public keys. For public key
+        PSA_ERROR_INVALID_ARGUMENT status is expected.
+        """
+        result = 'PSA_SUCCESS'
+
+        import_dependencies = [psa_want_symbol(kt.name)]
+        if kt.params is not None:
+            import_dependencies += [psa_want_symbol(sym)
+                                    for i, sym in enumerate(kt.params)]
+        if kt.name.endswith('_PUBLIC_KEY'):
+            # The library checks whether the key type is a public key generically,
+            # before it reaches a point where it needs support for the specific key
+            # type, so it returns INVALID_ARGUMENT for unsupported public key types.
+            generate_dependencies = []
+            result = 'PSA_ERROR_INVALID_ARGUMENT'
+        else:
+            generate_dependencies = import_dependencies
+            if kt.name == 'PSA_KEY_TYPE_RSA_KEY_PAIR':
+                generate_dependencies.append("MBEDTLS_GENPRIME")
+        for bits in kt.sizes_to_test():
+            yield test_case_for_key_generation(
+                kt.expression, bits,
+                finish_family_dependencies(generate_dependencies, bits),
+                str(bits),
+                result
+            )
+
+    def test_cases_for_key_generation(self) -> Iterator[test_case.TestCase]:
+        """Generate test cases that exercise the generation of keys."""
+        for key_type in sorted(self.constructors.key_types):
+            if key_type in self.ECC_KEY_TYPES:
+                continue
+            kt = crypto_knowledge.KeyType(key_type)
+            yield from self.test_cases_for_key_type_key_generation(kt)
+        for curve_family in sorted(self.constructors.ecc_curves):
+            for constr in self.ECC_KEY_TYPES:
+                kt = crypto_knowledge.KeyType(constr, [curve_family])
+                yield from self.test_cases_for_key_type_key_generation(kt)
+
 class StorageKey(psa_storage.Key):
     """Representation of a key for storage format testing."""
 
@@ -682,6 +726,8 @@
         test_case.write_data_file(filename, test_cases)
 
     TARGETS = {
+        'test_suite_psa_crypto_generate_key.generated':
+        lambda info: KeyGenerate(info).test_cases_for_key_generation(),
         'test_suite_psa_crypto_not_supported.generated':
         lambda info: NotSupported(info).test_cases_for_not_supported(),
         'test_suite_psa_crypto_storage_format.current':
diff --git a/tests/scripts/test_psa_compliance.py b/tests/scripts/test_psa_compliance.py
new file mode 100755
index 0000000..ea52c93
--- /dev/null
+++ b/tests/scripts/test_psa_compliance.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+"""Run the PSA Cryto API compliance test suite.
+Clone the repo and check out the commit specified by PSA_ARCH_TEST_REPO and PSA_ARCH_TEST_REF,
+then complie and run the test suite. The clone is stored at <Mbed TLS root>/psa-arch-tests.
+Known defects in either the test suite or mbedtls - identified by their test number - are ignored,
+while unexpected failures AND successes are reported as errors,
+to help keep the list of known defects as up to date as possible.
+"""
+
+# Copyright The Mbed TLS Contributors
+# 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.
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+# PSA Compliance tests we expect to fail due to known defects in Mbed TLS (or the test suite)
+# The test numbers correspond to the numbers used by the console output of the test suite.
+# Test number 2xx corresponds to the files in the folder
+# psa-arch-tests/api-tests/dev_apis/crypto/test_c0xx
+EXPECTED_FAILURES = {
+    # Multipart CCM is not supported.
+    # - Tracked in issue #3721
+    252, 253, 254, 255, 256, 257, 258, 259, 261,
+
+    # psa_hash_suspend() and psa_hash_resume() are not supported.
+    # - Tracked in issue #3274
+    262, 263
+}
+
+# We currently use a fork of ARM-software/psa-arch-tests, with a couple of downstream patches
+# that allow it to build with MbedTLS 3, and fixes a couple of issues in the compliance test suite.
+# These fixes allow the tests numbered 216, 248 and 249 to complete successfully.
+#
+# Once all the fixes are upstreamed, this fork should be replaced with an upstream commit/tag.
+# - Tracked in issue #5145
+#
+# Web URL: https://github.com/bensze01/psa-arch-tests/tree/fixes-for-mbedtls-3
+PSA_ARCH_TESTS_REPO = 'https://github.com/bensze01/psa-arch-tests.git'
+PSA_ARCH_TESTS_REF = 'fixes-for-mbedtls-3'
+
+#pylint: disable=too-many-branches,too-many-statements
+def main():
+    mbedtls_dir = os.getcwd()
+
+    if not os.path.exists('library/libmbedcrypto.a'):
+        subprocess.check_call(['make', '-C', 'library', 'libmbedcrypto.a'])
+
+    psa_arch_tests_dir = 'psa-arch-tests'
+    os.makedirs(psa_arch_tests_dir, exist_ok=True)
+    try:
+        os.chdir(psa_arch_tests_dir)
+
+        # Reuse existing local clone
+        subprocess.check_call(['git', 'init'])
+        subprocess.check_call(['git', 'fetch', PSA_ARCH_TESTS_REPO, PSA_ARCH_TESTS_REF])
+        subprocess.check_call(['git', 'checkout', 'FETCH_HEAD'])
+
+        build_dir = 'api-tests/build'
+        try:
+            shutil.rmtree(build_dir)
+        except FileNotFoundError:
+            pass
+        os.mkdir(build_dir)
+        os.chdir(build_dir)
+
+        #pylint: disable=bad-continuation
+        subprocess.check_call([
+            'cmake', '..',
+                     '-GUnix Makefiles',
+                     '-DTARGET=tgt_dev_apis_stdc',
+                     '-DTOOLCHAIN=HOST_GCC',
+                     '-DSUITE=CRYPTO',
+                     '-DPSA_CRYPTO_LIB_FILENAME={}/library/libmbedcrypto.a'.format(mbedtls_dir),
+                     '-DPSA_INCLUDE_PATHS={}/include'.format(mbedtls_dir)
+        ])
+        subprocess.check_call(['cmake', '--build', '.'])
+
+        proc = subprocess.Popen(['./psa-arch-tests-crypto'],
+                                bufsize=1, stdout=subprocess.PIPE, universal_newlines=True)
+
+        test_re = re.compile(
+            '^TEST: (?P<test_num>[0-9]*)|'
+            '^TEST RESULT: (?P<test_result>FAILED|PASSED)'
+        )
+        test = -1
+        unexpected_successes = set(EXPECTED_FAILURES)
+        expected_failures = []
+        unexpected_failures = []
+        for line in proc.stdout:
+            print(line, end='')
+            match = test_re.match(line)
+            if match is not None:
+                groupdict = match.groupdict()
+                test_num = groupdict['test_num']
+                if test_num is not None:
+                    test = int(test_num)
+                elif groupdict['test_result'] == 'FAILED':
+                    try:
+                        unexpected_successes.remove(test)
+                        expected_failures.append(test)
+                        print('Expected failure, ignoring')
+                    except KeyError:
+                        unexpected_failures.append(test)
+                        print('ERROR: Unexpected failure')
+                elif test in unexpected_successes:
+                    print('ERROR: Unexpected success')
+        proc.wait()
+
+        print()
+        print('***** test_psa_compliance.py report ******')
+        print()
+        print('Expected failures:', ', '.join(str(i) for i in expected_failures))
+        print('Unexpected failures:', ', '.join(str(i) for i in unexpected_failures))
+        print('Unexpected successes:', ', '.join(str(i) for i in sorted(unexpected_successes)))
+        print()
+        if unexpected_successes or unexpected_failures:
+            if unexpected_successes:
+                print('Unexpected successes encountered.')
+                print('Please remove the corresponding tests from '
+                      'EXPECTED_FAILURES in tests/scripts/compliance_test.py')
+                print()
+            print('FAILED')
+            return 1
+        else:
+            print('SUCCESS')
+            return 0
+    finally:
+        os.chdir(mbedtls_dir)
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c
index d9d841a..299b6d1 100644
--- a/tests/src/psa_crypto_helpers.c
+++ b/tests/src/psa_crypto_helpers.c
@@ -22,6 +22,7 @@
 
 #include <test/helpers.h>
 #include <test/macros.h>
+#include <psa_crypto_slot_management.h>
 #include <test/psa_crypto_helpers.h>
 
 #if defined(MBEDTLS_PSA_CRYPTO_C)
diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c
index 91bac67..fc58fbd 100644
--- a/tests/src/psa_exercise_key.c
+++ b/tests/src/psa_exercise_key.c
@@ -29,6 +29,7 @@
 #include <psa/crypto.h>
 
 #include <test/asn1_helpers.h>
+#include <psa_crypto_slot_management.h>
 #include <test/psa_crypto_helpers.h>
 
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 9930210..d43d662 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -79,16 +79,20 @@
 
 if [ -n "${OPENSSL_NEXT:-}" ]; then
     O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
+    O_NEXT_SRV_RSA="$OPENSSL_NEXT s_server -www -cert data_files/server2-sha256.crt -key data_files/server2.key"
     O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
 else
     O_NEXT_SRV=false
+    O_NEXT_SRV_RSA=false
     O_NEXT_CLI=false
 fi
 
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
     G_NEXT_SRV="$GNUTLS_NEXT_SERV --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
+    G_NEXT_SRV_RSA="$GNUTLS_NEXT_SERV --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key"
 else
     G_NEXT_SRV=false
+    G_NEXT_SRV_RSA=false
 fi
 
 if [ -n "${GNUTLS_NEXT_CLI:-}" ]; then
@@ -264,7 +268,7 @@
 # Space-separated list of ciphersuites supported by this build of
 # Mbed TLS.
 P_CIPHERSUITES=" $($P_CLI --help 2>/dev/null |
-                   grep TLS- |
+                   grep 'TLS-\|TLS1-3' |
                    tr -s ' \n' ' ')"
 requires_ciphersuite_enabled() {
     case $P_CIPHERSUITES in
@@ -1416,11 +1420,13 @@
 
 if [ -n "${OPENSSL_NEXT:-}" ]; then
     O_NEXT_SRV="$O_NEXT_SRV -accept $SRV_PORT"
+    O_NEXT_SRV_RSA="$O_NEXT_SRV_RSA -accept $SRV_PORT"
     O_NEXT_CLI="$O_NEXT_CLI -connect 127.0.0.1:+SRV_PORT"
 fi
 
 if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
     G_NEXT_SRV="$G_NEXT_SRV -p $SRV_PORT"
+    G_NEXT_SRV_RSA="$G_NEXT_SRV_RSA -p $SRV_PORT"
 fi
 
 if [ -n "${GNUTLS_NEXT_CLI:-}" ]; then
@@ -8809,12 +8815,10 @@
 requires_openssl_tls1_3
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
 requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
-run_test    "TLS1.3: Test client hello msg work - openssl" \
-            "$O_NEXT_SRV -tls1_3 -msg -no_middlebox" \
+run_test    "TLS1.3: minimal feature sets - openssl" \
+            "$O_NEXT_SRV -msg -tls1_3 -no_middlebox -num_tickets 0 -no_resume_ephemeral -no_cache" \
             "$P_CLI debug_level=3 min_version=tls1_3 max_version=tls1_3" \
-            1 \
-            -c "SSL - The requested feature is not available" \
-            -s "ServerHello"                \
+            0 \
             -c "tls1_3 client state: 0"     \
             -c "tls1_3 client state: 2"     \
             -c "tls1_3 client state: 19"    \
@@ -8822,8 +8826,6 @@
             -c "tls1_3 client state: 3"     \
             -c "tls1_3 client state: 9"     \
             -c "tls1_3 client state: 13"    \
-            -c "tls1_3 client state: 7"     \
-            -c "tls1_3 client state: 20"    \
             -c "tls1_3 client state: 11"    \
             -c "tls1_3 client state: 14"    \
             -c "tls1_3 client state: 15"    \
@@ -8831,19 +8833,39 @@
             -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
             -c "ECDH curve: x25519"         \
             -c "=> ssl_tls1_3_process_server_hello" \
+            -c "<= parse encrypted extensions"      \
             -c "Certificate verification flags clear" \
-            -c "<= parse encrypted extensions"
+            -c "=> parse certificate verify"          \
+            -c "<= parse certificate verify"          \
+            -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \
+            -c "<= parse finished message" \
+            -c "HTTP/1.0 200 ok"
+
+requires_openssl_tls1_3
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test    "TLS 1.3 m->O AES_128_GCM_SHA256      , RSA_PSS_RSAE_SHA256" \
+            "$O_NEXT_SRV_RSA -ciphersuites TLS_AES_128_GCM_SHA256 -tls1_3 -msg -no_middlebox -num_tickets 0" \
+            "$P_CLI debug_level=4 force_version=tls1_3 server_name=localhost force_ciphersuite=TLS1-3-AES-128-GCM-SHA256 allow_sha1=0" \
+            0 \
+            -c "ECDH curve: x25519" \
+            -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
+            -c "Certificate Verify: Signature algorithm ( 0804 )" \
+            -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \
+            -c "HTTP/1.0 200 ok"
 
 requires_gnutls_tls1_3
 requires_gnutls_next_no_ticket
 requires_gnutls_next_disable_tls13_compat
 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
 requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
-run_test    "TLS1.3: Test client hello msg work - gnutls" \
+run_test    "TLS1.3: minimal feature sets - gnutls" \
             "$G_NEXT_SRV --debug=4 --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:+CIPHER-ALL:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE --disable-client-cert" \
             "$P_CLI debug_level=3 min_version=tls1_3 max_version=tls1_3" \
-            1 \
-            -c "SSL - The requested feature is not available" \
+            0 \
             -s "SERVER HELLO was queued"    \
             -c "tls1_3 client state: 0"     \
             -c "tls1_3 client state: 2"     \
@@ -8852,8 +8874,6 @@
             -c "tls1_3 client state: 3"     \
             -c "tls1_3 client state: 9"     \
             -c "tls1_3 client state: 13"    \
-            -c "tls1_3 client state: 7"     \
-            -c "tls1_3 client state: 20"    \
             -c "tls1_3 client state: 11"    \
             -c "tls1_3 client state: 14"    \
             -c "tls1_3 client state: 15"    \
@@ -8861,8 +8881,31 @@
             -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
             -c "ECDH curve: x25519"         \
             -c "=> ssl_tls1_3_process_server_hello" \
+            -c "<= parse encrypted extensions"      \
             -c "Certificate verification flags clear" \
-            -c "<= parse encrypted extensions"
+            -c "=> parse certificate verify"          \
+            -c "<= parse certificate verify"          \
+            -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \
+            -c "<= parse finished message" \
+            -c "HTTP/1.0 200 OK"
+
+requires_gnutls_next_no_ticket
+requires_gnutls_next_disable_tls13_compat
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+requires_config_enabled MBEDTLS_DEBUG_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_enabled MBEDTLS_X509_RSASSA_PSS_SUPPORT
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+requires_gnutls_next
+run_test    "TLS 1.3 m->G AES_128_GCM_SHA256      , RSA_PSS_RSAE_SHA256" \
+            "$G_NEXT_SRV_RSA --disable-client-cert --priority=NORMAL:+CIPHER-ALL:+SHA256:+GROUP-SECP256R1:+ECDHE-ECDSA:+AEAD:+SIGN-RSA-PSS-RSAE-SHA256:-VERS-ALL:+VERS-TLS1.3:%NO_TICKETS:%DISABLE_TLS13_COMPAT_MODE" \
+            "$P_CLI debug_level=4 force_version=tls1_3 server_name=localhost force_ciphersuite=TLS1-3-AES-128-GCM-SHA256 allow_sha1=0" \
+            0 \
+            -c "ECDH curve: x25519"         \
+            -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \
+            -c "Certificate Verify: Signature algorithm ( 0804 )" \
+            -c "mbedtls_ssl_tls13_process_certificate_verify() returned 0" \
+            -c "HTTP/1.0 200 OK"
 
 # Test heap memory usage after handshake
 requires_config_enabled MBEDTLS_MEMORY_DEBUG
diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data
index 591e0d9..61e6e9b 100644
--- a/tests/suites/test_suite_ccm.data
+++ b/tests/suites/test_suite_ccm.data
@@ -1744,3 +1744,11 @@
 CCM encrypt, unexpected ciphertext/plaintext data, NIST VPT AES-128 #14 (P=13, N=13, A=32, T=16)
 depends_on:MBEDTLS_AES_C
 mbedtls_ccm_unexpected_text:MBEDTLS_CIPHER_ID_AES:MBEDTLS_CCM_ENCRYPT:"d32088d50df9aba14d9022c870a0cb85":"4b10788c1a03bca656f04f1f98":"e16c69861efc206e85aab1255e":"0eff7d7bcceb873c3203a8df74f4e91b04bd607ec11202f96cfeb99f5bcdb7aa"
+
+CCM* encrypt, no auth NIST VADT AES-256 #1 (P=24, N=13)
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_no_tag:MBEDTLS_CIPHER_ID_AES:MBEDTLS_CCM_STAR_ENCRYPT:"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886df3ba3e6da3a1389":"30d56ff2a25b83fee791110fcaea48e41db7c7f098a81000":"72a60f345a1978fb40f28a2fa4":"55f068c0bbba8b598013dd1841fd740fda2902322148ab5e"
+
+CCM* decrypt, no auth NIST DVPT AES-128 #15 (P=24, N=13)
+depends_on:MBEDTLS_AES_C
+mbedtls_ccm_star_no_tag:MBEDTLS_CIPHER_ID_AES:MBEDTLS_CCM_STAR_DECRYPT:"90929a4b0ac65b350ad1591611fe4829":"4bfe4e35784f0a65b545477e5e2f4bae0e1e6fa717eaf2cb":"5a8aa485c316e9403aff859fbb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697"
diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function
index e48b1f9..a7ba0de 100644
--- a/tests/suites/test_suite_ccm.function
+++ b/tests/suites/test_suite_ccm.function
@@ -232,6 +232,31 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mbedtls_ccm_star_no_tag( int cipher_id, int mode, data_t * key,
+                              data_t * msg, data_t * iv, data_t * result )
+{
+    mbedtls_ccm_context ctx;
+    uint8_t *output = NULL;
+    size_t olen;
+
+    mbedtls_ccm_init( &ctx );
+    TEST_EQUAL( mbedtls_ccm_setkey( &ctx, cipher_id, key->x, key->len * 8 ), 0 );
+    TEST_EQUAL( 0, mbedtls_ccm_starts( &ctx, mode, iv->x, iv->len ) );
+    TEST_EQUAL( 0, mbedtls_ccm_set_lengths( &ctx, 0, msg->len, 0 ) );
+
+    ASSERT_ALLOC( output, msg->len );
+    TEST_EQUAL( 0, mbedtls_ccm_update( &ctx, msg->x, msg->len, output, msg->len, &olen ) );
+    TEST_EQUAL( result->len, olen );
+    ASSERT_COMPARE( output, olen, result->x, result->len );
+
+    TEST_EQUAL( 0, mbedtls_ccm_finish( &ctx, NULL, 0 ) );
+exit:
+    mbedtls_free(output);
+    mbedtls_ccm_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mbedtls_ccm_auth_decrypt( int cipher_id, data_t * key,
                                data_t * msg, data_t * iv,
                                data_t * add, int expected_tag_len, int result,
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index c8fbca2..8c2ba3c 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -790,6 +790,318 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_OFB
 enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_OFB:256:16:16:-1:16:16:16:16
 
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:0:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:1:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:2:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:7:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:8:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:9:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:15:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:16:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:17:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:31:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:32:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:33:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:47:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:48:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:"AES-128-CCM*-NO-TAG":128:49:-1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:0:0:-1:0:0:0:0
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:1:0:-1:1:0:1:0
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:0:1:-1:0:1:0:1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:16:0:-1:16:0:16:0
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:0:16:-1:0:16:0:16
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:1:15:-1:1:15:1:15
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:15:1:-1:15:1:15:1
+
+AES-128 CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:15:7:-1:15:7:15:7
+
+AES-128-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:16:6:-1:16:6:16:6
+
+AES-128-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:17:6:-1:17:6:17:6
+
+AES-128-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:128:16:16:-1:16:16:16:16
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:0:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:1:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:2:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:7:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:8:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:9:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:15:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:16:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:17:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:31:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:32:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:33:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:47:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:48:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:"AES-192-CCM*-NO-TAG":192:49:-1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:0:0:-1:0:0:0:0
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:1:0:-1:1:0:1:0
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:0:1:-1:0:1:0:1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:16:0:-1:16:0:16:0
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:0:16:-1:0:16:0:16
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:1:15:-1:1:15:1:15
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:15:1:-1:15:1:15:1
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:15:7:-1:15:7:15:7
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:16:6:-1:16:6:16:6
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:17:6:-1:17:6:17:6
+
+AES-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:192:16:16:-1:16:16:16:16
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:0:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:1:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:2:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:7:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:8:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:9:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:15:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:16:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:17:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:31:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:32:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:33:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:47:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:48:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:"AES-256-CCM*-NO-TAG":256:49:-1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:0:0:-1:0:0:0:0
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:1:0:-1:1:0:1:0
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:0:1:-1:0:1:0:1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:16:0:-1:16:0:16:0
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:0:16:-1:0:16:0:16
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:1:15:-1:1:15:1:15
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:15:1:-1:15:1:15:1
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:15:7:-1:15:7:15:7
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:16:6:-1:16:6:16:6
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:17:6:-1:17:6:17:6
+
+AES-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:256:16:16:-1:16:16:16:16
+
 AES-128 XTS - Encrypt and decrypt 16 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS
 enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:16:-1
@@ -1894,6 +2206,54 @@
 depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C
 test_vec_crypt:MBEDTLS_CIPHER_AES_256_ECB:MBEDTLS_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"":"5c9d844ed46f9885085e5d6a4f94c7d7":"014730f80ac625fe84f026c60bfd547d":0:1
 
+AES-128-CCM*-NO-TAG crypt Encrypt NIST VPT AES-128 #15
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"7301c907b9d2aaac355c5416ff25c59b":"7304b65b6dab466273862c88b9":"484300aa3a506afcd313b49ead8d":"928ca58b0d373dc50c52afac787c":0:0
+
+AES-128-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-128 #15
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"90929a4b0ac65b350ad1591611fe4829":"5a8aa485c316e9403aff859fbb":"4bfe4e35784f0a65b545477e5e2f4bae0e1e6fa717eaf2cb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":0:0
+
+AES-192-CCM*-NO-TAG crypt Encrypt NIST VTT AES-192 #1
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"11fd45743d946e6d37341fec49947e8c70482494a8f07fcc":"c6aeebcb146cfafaae66f78aab":"ee7e6075ba52846de5d6254959a18affc4faf59c8ef63489":"137d9da59baf5cbfd46620c5f298fc766de10ac68e774edf":0:0
+
+AES-192-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-192 #15
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"90929a4b0ac65b350ad1591611fe48297e03956f6083e451":"5a8aa485c316e9403aff859fbb":"a5b7d8cca2069908d1ed88e6a9fe2c9bede3131dad54671e":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":0:0
+
+AES-256-CCM*-NO-TAG crypt Encrypt NIST VADT AES-256 #1
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886df3ba3e6da3a1389":"72a60f345a1978fb40f28a2fa4":"30d56ff2a25b83fee791110fcaea48e41db7c7f098a81000":"55f068c0bbba8b598013dd1841fd740fda2902322148ab5e":0:0
+
+AES-256-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-256 #13
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453":"a544218dadd3c10583db49cf39":"63e00d30e4b08fd2a1cc8d70fab327b2368e77a93be4f412":"3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e":0:0
+
+AES-128-CCM*-NO-TAG crypt Encrypt NIST VPT AES-128 #15 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"7301c907b9d2aaac355c5416ff25c59b":"7304b65b6dab466273862c88b9":"484300aa3a506afcd313b49ead8d":"928ca58b0d373dc50c52afac787c":0:1
+
+AES-128-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-128 #15 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"90929a4b0ac65b350ad1591611fe4829":"5a8aa485c316e9403aff859fbb":"4bfe4e35784f0a65b545477e5e2f4bae0e1e6fa717eaf2cb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":0:1
+
+AES-192-CCM*-NO-TAG crypt Encrypt NIST VTT AES-192 #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"11fd45743d946e6d37341fec49947e8c70482494a8f07fcc":"c6aeebcb146cfafaae66f78aab":"ee7e6075ba52846de5d6254959a18affc4faf59c8ef63489":"137d9da59baf5cbfd46620c5f298fc766de10ac68e774edf":0:1
+
+AES-192-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-192 #15 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"90929a4b0ac65b350ad1591611fe48297e03956f6083e451":"5a8aa485c316e9403aff859fbb":"a5b7d8cca2069908d1ed88e6a9fe2c9bede3131dad54671e":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":0:1
+
+AES-256-CCM*-NO-TAG crypt Encrypt NIST VADT AES-256 #1 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"26511fb51fcfa75cb4b44da75a6e5a0eb8d9c8f3b906f886df3ba3e6da3a1389":"72a60f345a1978fb40f28a2fa4":"30d56ff2a25b83fee791110fcaea48e41db7c7f098a81000":"55f068c0bbba8b598013dd1841fd740fda2902322148ab5e":0:1
+
+AES-256-CCM*-NO-TAG crypt Decrypt NIST DVPT AES-256 #13 PSA
+depends_on:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_AES_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"f7079dfa3b5c7b056347d7e437bcded683abd6e2c9e069d333284082cbb5d453":"a544218dadd3c10583db49cf39":"63e00d30e4b08fd2a1cc8d70fab327b2368e77a93be4f412":"3c0e2815d37d844f7ac240ba9d6e3a0b2a86f706e885959e":0:1
+
 Cipher Corner Case behaviours
 depends_on:MBEDTLS_AES_C
 cipher_special_behaviours:
diff --git a/tests/suites/test_suite_cipher.aria.data b/tests/suites/test_suite_cipher.aria.data
index 2c50a21..c1e1990 100644
--- a/tests/suites/test_suite_cipher.aria.data
+++ b/tests/suites/test_suite_cipher.aria.data
@@ -1,3 +1,339 @@
 Aria CBC Decrypt empty buffer
 depends_on:MBEDTLS_ARIA_C:MBEDTLS_CIPHER_MODE_CBC
 dec_empty_buf:MBEDTLS_CIPHER_ARIA_128_CBC:0:0
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:0:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:1:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:2:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:7:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:8:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:9:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:15:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:16:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:17:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:31:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:32:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:33:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:47:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:48:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:"ARIA-128-CCM*-NO-TAG":128:49:-1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:0:0:-1:0:0:0:0
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:1:0:-1:1:0:1:0
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:0:1:-1:0:1:0:1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:16:0:-1:16:0:16:0
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:0:16:-1:0:16:0:16
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:1:15:-1:1:15:1:15
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:15:1:-1:15:1:15:1
+
+ARIA-128 CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:15:7:-1:15:7:15:7
+
+ARIA-128-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:16:6:-1:16:6:16:6
+
+ARIA-128-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:17:6:-1:17:6:17:6
+
+ARIA-128-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:128:16:16:-1:16:16:16:16
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:0:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:1:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:2:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:7:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:8:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:9:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:15:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:16:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:17:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:31:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:32:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:33:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:47:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:48:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:"ARIA-192-CCM*-NO-TAG":192:49:-1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:0:0:-1:0:0:0:0
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:1:0:-1:1:0:1:0
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:0:1:-1:0:1:0:1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:16:0:-1:16:0:16:0
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:0:16:-1:0:16:0:16
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:1:15:-1:1:15:1:15
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:15:1:-1:15:1:15:1
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:15:7:-1:15:7:15:7
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:16:6:-1:16:6:16:6
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:17:6:-1:17:6:17:6
+
+ARIA-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:192:16:16:-1:16:16:16:16
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:0:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:1:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:2:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:7:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:8:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:9:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:15:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:16:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:17:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:31:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:32:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:33:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:47:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:48:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:"ARIA-256-CCM*-NO-TAG":256:49:-1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:0:0:-1:0:0:0:0
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:1:0:-1:1:0:1:0
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:0:1:-1:0:1:0:1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:16:0:-1:16:0:16:0
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:0:16:-1:0:16:0:16
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:1:15:-1:1:15:1:15
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:15:1:-1:15:1:15:1
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:15:7:-1:15:7:15:7
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:16:6:-1:16:6:16:6
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:17:6:-1:17:6:17:6
+
+ARIA-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:256:16:16:-1:16:16:16:16
+
+ARIA-128-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"6781f39fdf8d1c44165fc40ee2fb11f1d6e2ddc8c6512b":0:0
+
+ARIA-128-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"6781f39fdf8d1c44165fc40ee2fb11f1d6e2ddc8c6512b":0:0
+
+ARIA-192-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"993df86214d98ae70582c784903702e349dd64ece488c2":0:0
+
+ARIA-192-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"993df86214d98ae70582c784903702e349dd64ece488c2":0:0
+
+ARIA-256-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"5fdd984a6aa77c1d9a204c08f28172c4b4528bee27c41f":0:0
+
+ARIA-256-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_ARIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"5fdd984a6aa77c1d9a204c08f28172c4b4528bee27c41f":0:0
diff --git a/tests/suites/test_suite_cipher.camellia.data b/tests/suites/test_suite_cipher.camellia.data
index 3e7bffa..31fe922 100644
--- a/tests/suites/test_suite_cipher.camellia.data
+++ b/tests/suites/test_suite_cipher.camellia.data
@@ -765,3 +765,339 @@
 CAMELLIA Encrypt and decrypt 32 bytes in multiple parts 1 [#5]
 depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
 enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CBC:256:16:16:-1:16:16:0:32
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:0:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:1:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:2:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:7:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:8:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:9:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:15:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:16:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:17:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:31:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:32:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:33:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:47:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:48:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:"CAMELLIA-128-CCM*-NO-TAG":128:49:-1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:0:0:-1:0:0:0:0
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:1:0:-1:1:0:1:0
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:0:1:-1:0:1:0:1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:16:0:-1:16:0:16:0
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:0:16:-1:0:16:0:16
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:1:15:-1:1:15:1:15
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:15:1:-1:15:1:15:1
+
+CAMELLIA-128 CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:15:7:-1:15:7:15:7
+
+CAMELLIA-128-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:16:6:-1:16:6:16:6
+
+CAMELLIA-128-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:17:6:-1:17:6:17:6
+
+CAMELLIA-128-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:128:16:16:-1:16:16:16:16
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:0:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:1:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:2:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:7:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:8:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:9:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:15:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:16:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:17:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:31:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:32:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:33:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:47:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:48:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:"CAMELLIA-192-CCM*-NO-TAG":192:49:-1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:0:0:-1:0:0:0:0
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:1:0:-1:1:0:1:0
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:0:1:-1:0:1:0:1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:16:0:-1:16:0:16:0
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:0:16:-1:0:16:0:16
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:1:15:-1:1:15:1:15
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:15:1:-1:15:1:15:1
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:15:7:-1:15:7:15:7
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:16:6:-1:16:6:16:6
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:17:6:-1:17:6:17:6
+
+CAMELLIA-192-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:192:16:16:-1:16:16:16:16
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:0:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 byte
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:1:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:2:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:7:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:8:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:9:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:15:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:16:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:17:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:31:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:32:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:33:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:47:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:48:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:"CAMELLIA-256-CCM*-NO-TAG":256:49:-1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 0 bytes in multiple parts
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:0:0:-1:0:0:0:0
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:1:0:-1:1:0:1:0
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:0:1:-1:0:1:0:1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:16:0:-1:16:0:16:0
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:0:16:-1:0:16:0:16
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:1:15:-1:1:15:1:15
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:15:1:-1:15:1:15:1
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:15:7:-1:15:7:15:7
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:16:6:-1:16:6:16:6
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 23 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:17:6:-1:17:6:17:6
+
+CAMELLIA-256-CCM*-NO-TAG - Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:256:16:16:-1:16:16:16:16
+
+CAMELLIA-128-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"BA737185E719310492F38A5F1251DA55FAFBC949848A0D":0:0
+
+CAMELLIA-128-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"BA737185E719310492F38A5F1251DA55FAFBC949848A0D":0:0
+
+CAMELLIA-192-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"c3ceaa2a68fb31d8347a83950f25f3a7956b8a284a5b35":0:0
+
+CAMELLIA-192-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"c3ceaa2a68fb31d8347a83950f25f3a7956b8a284a5b35":0:0
+
+CAMELLIA-256-CCM*-NO-TAG crypt Encrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:MBEDTLS_ENCRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"933f749801d0e1262cd101831defd8366ab2a22e7c03cd":0:0
+
+CAMELLIA-256-CCM*-NO-TAG crypt Decrypt
+depends_on:MBEDTLS_CAMELLIA_C:MBEDTLS_CCM_C
+test_vec_crypt:MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG:MBEDTLS_DECRYPT:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":"00000003020100A0A1A2A3A4A5":"08090A0B0C0D0E0F101112131415161718191A1B1C1D1E":"933f749801d0e1262cd101831defd8366ab2a22e7c03cd":0:0
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index c809d9a..e496856 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -343,7 +343,7 @@
 void enc_dec_buf( int cipher_id, char * cipher_string, int key_len,
                   int length_val, int pad_mode )
 {
-    size_t length = length_val, outlen, total_len, i, block_size;
+    size_t length = length_val, outlen, total_len, i, block_size, iv_len;
     unsigned char key[64];
     unsigned char iv[16];
     unsigned char ad[13];
@@ -401,8 +401,14 @@
     memset( decbuf, 0, sizeof( decbuf ) );
     memset( tag, 0, sizeof( tag ) );
 
-    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, sizeof( iv ) ) );
-    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, sizeof( iv ) ) );
+    if( NULL != strstr( cipher_info->name, "CCM*-NO-TAG") )
+        iv_len = 13; /* For CCM, IV length is expected to be between 7 and 13 bytes.
+                      * For CCM*-NO-TAG, IV length must be exactly 13 bytes long. */
+    else
+        iv_len = sizeof(iv);
+
+    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, iv_len ) );
+    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, iv_len ) );
 
     TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
     TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
@@ -597,6 +603,7 @@
     size_t second_length = second_length_val;
     size_t length = first_length + second_length;
     size_t block_size;
+    size_t iv_len;
     unsigned char key[32];
     unsigned char iv[16];
 
@@ -641,8 +648,14 @@
     (void) pad_mode;
 #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
 
-    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, 16 ) );
-    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, 16 ) );
+    if( NULL != strstr( cipher_info->name, "CCM*-NO-TAG") )
+        iv_len = 13; /* For CCM, IV length is expected to be between 7 and 13 bytes.
+                      * For CCM*-NO-TAG, IV length must be exactly 13 bytes long. */
+    else
+        iv_len = sizeof(iv);
+
+    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_dec, iv, iv_len ) );
+    TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx_enc, iv, iv_len ) );
 
     TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
     TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index caac146..2c5537f 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -1963,6 +1963,10 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES
 cipher_encrypt_validation:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"eda4011239bc3ac9"
 
+PSA symmetric encrypt validation: CCM*-no-tag, 15 bytes, good
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validation:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"d24a3d3dde8c84830280cb87abad0bb3":"6bc1bee22e409f96e93d7e11739317"
+
 PSA symmetric encrypt multipart: AES-ECB, 0 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
@@ -2023,6 +2027,10 @@
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
 cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"c78e2b38139610e3":8:8:0:"817ca7d69b80d86a":PSA_SUCCESS
 
+PSA symmetric encrypt multipart: CCM*-no-tag, AES, 24 bytes, good
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_multipart:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"d24a3d3dde8c84830280cb87abad0bb3":"f1100035bb24a8d26004e0e24b":"7c86135ed9c2a515aaae0e9a208133897269220f30870006":10:10:14:"1faeb0ee2ca2cd52f0aa3966578344f24e69b742c4ab37ab":PSA_SUCCESS
+
 PSA cipher decrypt: without initialization
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt_fail:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"":"":"":PSA_ERROR_BAD_STATE
@@ -2055,6 +2063,10 @@
 depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt_fail:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee223":PSA_ERROR_INVALID_ARGUMENT
 
+PSA symetric decrypt: CCM*-no-tag, input too short (15 bytes)
+depends_on:MBEDTLS_AES_C
+cipher_decrypt_fail:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"19ebfde2d5468ba0a3031bde629b11fd":"5a8aa485c316e9":"2a2a2a2a2a2a2a2a":PSA_ERROR_INVALID_ARGUMENT
+
 PSA symmetric decrypt: AES-ECB, 0 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":""
@@ -2103,6 +2115,10 @@
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
 cipher_decrypt:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"817ca7d69b80d86a":"c78e2b38139610e3"
 
+PSA symmetric decrypt: CCM*-no-tag, NIST DVPT AES-128 #15
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_decrypt:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"90929a4b0ac65b350ad1591611fe4829":"5a8aa485c316e9403aff859fbb":"4bfe4e35784f0a65b545477e5e2f4bae0e1e6fa717eaf2cb":"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697"
+
 PSA symmetric decrypt multipart: AES-ECB, 0 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"":0:0:0:"":PSA_SUCCESS
@@ -2163,6 +2179,10 @@
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
 cipher_decrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"":"817ca7d69b80d86a":8:8:0:"c78e2b38139610e3":PSA_SUCCESS
 
+PSA symmetric decrypt multipart: CCM*-no-tag, 24 bytes, good
+depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_DES
+cipher_decrypt_multipart:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"197afb02ffbd8f699dacae87094d5243":"5a8aa485c316e9403aff859fbb":"4a550134f94455979ec4bf89ad2bd80d25a77ae94e456134":10:10:14:"a16a2e741f1cd9717285b6d882c1fc53655e9773761ad697":PSA_SUCCESS
+
 PSA symmetric encrypt/decrypt: AES-ECB, 16 bytes, good
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_verify_output:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
@@ -2183,6 +2203,22 @@
 depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES
 cipher_verify_output:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
 
+PSA symmetric encrypt/decrypt: CCM*-no-tag, AES
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_verify_output:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
+
+CCM*-no-tag encrypt, iv_length = 14, bad
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validate_iv_length:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"90929a4b0ac65b350ad1591611fe4829":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":14:PSA_ERROR_INVALID_ARGUMENT
+
+CCM*-no-tag encrypt, iv_length = 13, good
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validate_iv_length:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"90929a4b0ac65b350ad1591611fe4829":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":13:PSA_SUCCESS
+
+CCM*-no-tag encrypt, iv_length = 12, bad
+depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
+cipher_encrypt_validate_iv_length:PSA_ALG_CCM_STAR_NO_TAG:PSA_KEY_TYPE_AES:"90929a4b0ac65b350ad1591611fe4829":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":12:PSA_ERROR_INVALID_ARGUMENT
+
 PSA symmetric encryption multipart: AES-ECB, 16+16 bytes
 depends_on:PSA_WANT_ALG_ECB_NO_PADDING:PSA_WANT_KEY_TYPE_AES
 cipher_encrypt_multipart:PSA_ALG_ECB_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"3ad77bb40d7a3660a89ecaf32466ef9755ed5e9e066820fa52c729886d18854c":PSA_SUCCESS
@@ -2501,19 +2537,19 @@
 
 PSA AEAD decrypt: AES-CCM, invalid nonce length 6
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: AES-CCM, invalid nonce length 14
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: AES-CCM_8, invalid nonce length 6
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c090693056":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: AES-CCM_8, invalid nonce length 14
 depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd97200":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD encrypt/decrypt, AES-GCM, 19 bytes #1
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
@@ -2669,11 +2705,11 @@
 
 PSA AEAD decrypt: AES-GCM, nonce=0 (bad)
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: AES-GCM, nonce=0 (bad), TAG=12
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
-aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 12 ):"":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: AES-GCM, invalid tag length 18
 depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES
@@ -2785,11 +2821,11 @@
 
 PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=11, too short)
 depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
-aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243444546":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"0700000040414243444546":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD decrypt: ChaCha20-Poly1305 (nonce=13, too long)
 depends_on:PSA_WANT_ALG_CHACHA20_POLY1305:PSA_WANT_KEY_TYPE_CHACHA20
-aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"07000000404142434445464700":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_NOT_SUPPORTED
+aead_decrypt:PSA_KEY_TYPE_CHACHA20:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":PSA_ALG_CHACHA20_POLY1305:"07000000404142434445464700":"":"a0784d7a4716f3feb4f64e7f4b39bf04":"":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
@@ -4226,7 +4262,7 @@
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
 # Whether we get NOT_PERMITTED or BAD_STATE for the output is an implementation
 # detail.
-derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_NOT_PERMITTED
+derive_input:PSA_ALG_HKDF(PSA_ALG_SHA_256):PSA_KEY_DERIVATION_INPUT_SALT:PSA_KEY_TYPE_NONE:"":PSA_SUCCESS:PSA_KEY_DERIVATION_INPUT_SECRET:PSA_KEY_TYPE_RAW_DATA:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_DERIVATION_INPUT_INFO:PSA_KEY_TYPE_NONE:"":PSA_ERROR_BAD_STATE:PSA_KEY_TYPE_RAW_DATA:PSA_ERROR_BAD_STATE
 
 PSA key derivation: HKDF-SHA-256, direct secret, direct output
 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 01a0698..d28de0c 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -2864,6 +2864,40 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void cipher_encrypt_validate_iv_length( int alg, int key_type, data_t* key_data,
+                               data_t *input, int iv_length,
+                               int expected_result )
+{
+    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    size_t output_buffer_size = 0;
+    unsigned char *output = NULL;
+
+    output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len );
+    ASSERT_ALLOC( output, output_buffer_size );
+
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, key_type );
+
+    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+                                &key ) );
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
+    TEST_EQUAL( expected_result, psa_cipher_set_iv( &operation, output,
+                                                    iv_length ) );
+
+exit:
+    psa_cipher_abort( &operation );
+    mbedtls_free( output );
+    psa_destroy_key( key );
+    PSA_DONE( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void cipher_encrypt_alg_without_iv( int alg_arg,
                                     int key_type_arg,
                                     data_t *key_data,
@@ -5900,7 +5934,7 @@
     if( output_key_type != PSA_KEY_TYPE_NONE )
     {
         psa_reset_key_attributes( &attributes );
-        psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
+        psa_set_key_type( &attributes, output_key_type );
         psa_set_key_bits( &attributes, 8 );
         actual_output_status =
             psa_key_derivation_output_key( &attributes, &operation,
diff --git a/tests/suites/test_suite_psa_crypto_generate_key.function b/tests/suites/test_suite_psa_crypto_generate_key.function
new file mode 100644
index 0000000..dbe9a0e
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto_generate_key.function
@@ -0,0 +1,49 @@
+/* BEGIN_HEADER */
+
+#include "psa/crypto.h"
+#include "test/psa_crypto_helpers.h"
+
+#define INVALID_KEY_ID mbedtls_svc_key_id_make( 0, 0xfedcba98 )
+
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:MBEDTLS_PSA_CRYPTO_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void generate_key( int key_type_arg, int bits_arg, int expected_status_arg)
+{
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    mbedtls_svc_key_id_t key_id = INVALID_KEY_ID;
+
+    // key lifetiem, usage flags, algorithm are irrelevant for this test
+    psa_key_type_t key_type = key_type_arg;
+    size_t bits = bits_arg;
+    psa_status_t expected_status = expected_status_arg;
+
+    PSA_ASSERT( psa_crypto_init( ) );
+    psa_set_key_type( &attributes, key_type );
+    psa_set_key_bits( &attributes, bits );
+    TEST_EQUAL( psa_generate_key( &attributes, &key_id ),
+                expected_status );
+
+    // Verify attributes of the created key on success
+    if ( expected_status == PSA_SUCCESS )
+    {
+        psa_reset_key_attributes(&attributes);
+        PSA_ASSERT( psa_get_key_attributes( key_id, &attributes ) );
+        TEST_EQUAL( psa_get_key_lifetime( &attributes ), PSA_KEY_LIFETIME_VOLATILE );
+        TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
+        TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
+        TEST_EQUAL( psa_get_key_type( &attributes ), key_type );
+        TEST_EQUAL( psa_get_key_bits( &attributes ), bits );
+    }
+
+exit:
+    psa_reset_key_attributes(&attributes);
+    psa_destroy_key( key_id );
+    PSA_DONE( );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_psa_crypto_not_supported.function b/tests/suites/test_suite_psa_crypto_not_supported.function
index 0665230..e3253d8 100644
--- a/tests/suites/test_suite_psa_crypto_not_supported.function
+++ b/tests/suites/test_suite_psa_crypto_not_supported.function
@@ -50,22 +50,3 @@
     PSA_DONE( );
 }
 /* END_CASE */
-
-/* BEGIN_CASE */
-void generate_invalid_argument( int key_type, int bits )
-{
-    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-    mbedtls_svc_key_id_t key_id = INVALID_KEY_ID;
-
-    PSA_ASSERT( psa_crypto_init( ) );
-    psa_set_key_type( &attributes, key_type );
-    psa_set_key_bits( &attributes, bits );
-    TEST_EQUAL( psa_generate_key( &attributes, &key_id ),
-                PSA_ERROR_INVALID_ARGUMENT );
-    TEST_ASSERT( mbedtls_svc_key_id_equal( key_id, MBEDTLS_SVC_KEY_ID_INIT ) );
-
-exit:
-    psa_destroy_key( key_id );
-    PSA_DONE( );
-}
-/* END_CASE */
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 75eda1d..ee36a66 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -10,7 +10,7 @@
 
 #include <psa/crypto.h>
 
-#include <ssl_invasive.h>
+#include <constant_time_internal.h>
 
 #include <test/constant_flow.h>
 
@@ -2236,8 +2236,8 @@
 void ssl_mock_sanity( )
 {
     enum { MSGLEN = 105 };
-    unsigned char message[MSGLEN];
-    unsigned char received[MSGLEN];
+    unsigned char message[MSGLEN] = { 0 };
+    unsigned char received[MSGLEN] = { 0 };
     mbedtls_mock_socket socket;
 
     mbedtls_mock_socket_init( &socket );
@@ -4653,7 +4653,7 @@
 void ssl_cf_hmac( int hash )
 {
     /*
-     * Test the function mbedtls_ssl_cf_hmac() against a reference
+     * Test the function mbedtls_ct_hmac() against a reference
      * implementation.
      */
     mbedtls_md_context_t ctx, ref_ctx;
@@ -4712,10 +4712,10 @@
 
             /* Get the function's result */
             TEST_CF_SECRET( &in_len, sizeof( in_len ) );
-            TEST_EQUAL( 0, mbedtls_ssl_cf_hmac( &ctx, add_data, sizeof( add_data ),
-                                                data, in_len,
-                                                min_in_len, max_in_len,
-                                                out ) );
+            TEST_EQUAL( 0, mbedtls_ct_hmac( &ctx, add_data, sizeof( add_data ),
+                                            data, in_len,
+                                            min_in_len, max_in_len,
+                                            out ) );
             TEST_CF_PUBLIC( &in_len, sizeof( in_len ) );
             TEST_CF_PUBLIC( out, out_len );
 
@@ -4762,8 +4762,8 @@
         mbedtls_test_set_step( (int) secret );
 
         TEST_CF_SECRET( &secret, sizeof( secret ) );
-        mbedtls_ssl_cf_memcpy_offset( dst, src, secret,
-                                      offset_min, offset_max, len );
+        mbedtls_ct_memcpy_offset( dst, src, secret,
+                                  offset_min, offset_max, len );
         TEST_CF_PUBLIC( &secret, sizeof( secret ) );
         TEST_CF_PUBLIC( dst, len );