diff --git a/library/rsa.c b/library/rsa.c
new file mode 100644
index 0000000..698d1b1
--- /dev/null
+++ b/library/rsa.c
@@ -0,0 +1,2411 @@
+/*
+ *  The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of Mbed Crypto (https://tls.mbed.org)
+ */
+
+/*
+ *  The following sources were referenced in the design of this implementation
+ *  of the RSA algorithm:
+ *
+ *  [1] A method for obtaining digital signatures and public-key cryptosystems
+ *      R Rivest, A Shamir, and L Adleman
+ *      http://people.csail.mit.edu/rivest/pubs.html#RSA78
+ *
+ *  [2] Handbook of Applied Cryptography - 1997, Chapter 8
+ *      Menezes, van Oorschot and Vanstone
+ *
+ *  [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
+ *      Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
+ *      Stefan Mangard
+ *      https://arxiv.org/abs/1702.08719v2
+ *
+ */
+
+#if !defined(MBEDCRYPTO_CONFIG_FILE)
+#include "mbedcrypto/config.h"
+#else
+#include MBEDCRYPTO_CONFIG_FILE
+#endif
+
+#if defined(MBEDCRYPTO_RSA_C)
+
+#include "mbedcrypto/rsa.h"
+#include "mbedcrypto/rsa_internal.h"
+#include "mbedcrypto/oid.h"
+#include "mbedcrypto/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+#include "mbedcrypto/md.h"
+#endif
+
+#if defined(MBEDCRYPTO_PKCS1_V15) && !defined(__OpenBSD__)
+#include <stdlib.h>
+#endif
+
+#if defined(MBEDCRYPTO_PLATFORM_C)
+#include "mbedcrypto/platform.h"
+#else
+#include <stdio.h>
+#define mbedcrypto_printf printf
+#define mbedcrypto_calloc calloc
+#define mbedcrypto_free   free
+#endif
+
+#if !defined(MBEDCRYPTO_RSA_ALT)
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+/* constant-time buffer comparison */
+static inline int mbedcrypto_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 /* MBEDCRYPTO_PKCS1_V15 */
+
+int mbedcrypto_rsa_import( mbedcrypto_rsa_context *ctx,
+                        const mbedcrypto_mpi *N,
+                        const mbedcrypto_mpi *P, const mbedcrypto_mpi *Q,
+                        const mbedcrypto_mpi *D, const mbedcrypto_mpi *E )
+{
+    int ret;
+
+    if( ( N != NULL && ( ret = mbedcrypto_mpi_copy( &ctx->N, N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedcrypto_mpi_copy( &ctx->P, P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedcrypto_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedcrypto_mpi_copy( &ctx->D, D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedcrypto_mpi_copy( &ctx->E, E ) ) != 0 ) )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    if( N != NULL )
+        ctx->len = mbedcrypto_mpi_size( &ctx->N );
+
+    return( 0 );
+}
+
+int mbedcrypto_rsa_import_raw( mbedcrypto_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len )
+{
+    int ret = 0;
+
+    if( N != NULL )
+    {
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &ctx->N, N, N_len ) );
+        ctx->len = mbedcrypto_mpi_size( &ctx->N );
+    }
+
+    if( P != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    return( 0 );
+}
+
+/*
+ * Checks whether the context fields are set in such a way
+ * that the RSA primitives will be able to execute without error.
+ * It does *not* make guarantees for consistency of the parameters.
+ */
+static int rsa_check_context( mbedcrypto_rsa_context const *ctx, int is_priv,
+                              int blinding_needed )
+{
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    /* blinding_needed is only used for NO_CRT to decide whether
+     * P,Q need to be present or not. */
+    ((void) blinding_needed);
+#endif
+
+    if( ctx->len != mbedcrypto_mpi_size( &ctx->N ) ||
+        ctx->len > MBEDCRYPTO_MPI_MAX_SIZE )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /*
+     * 1. Modular exponentiation needs positive, odd moduli.
+     */
+
+    /* Modular exponentiation wrt. N is always used for
+     * RSA public key operations. */
+    if( mbedcrypto_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
+        mbedcrypto_mpi_get_bit( &ctx->N, 0 ) == 0  )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    /* Modular exponentiation for P and Q is only
+     * used for private key operations and if CRT
+     * is used. */
+    if( is_priv &&
+        ( mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedcrypto_mpi_get_bit( &ctx->P, 0 ) == 0 ||
+          mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
+          mbedcrypto_mpi_get_bit( &ctx->Q, 0 ) == 0  ) )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* !MBEDCRYPTO_RSA_NO_CRT */
+
+    /*
+     * 2. Exponents must be positive
+     */
+
+    /* Always need E for public key operations */
+    if( mbedcrypto_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+    /* For private key operations, use D or DP & DQ
+     * as (unblinded) exponents. */
+    if( is_priv && mbedcrypto_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+#else
+    if( is_priv &&
+        ( mbedcrypto_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
+          mbedcrypto_mpi_cmp_int( &ctx->DQ, 0 ) <= 0  ) )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+    /* Blinding shouldn't make exponents negative either,
+     * so check that P, Q >= 1 if that hasn't yet been
+     * done as part of 1. */
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+    if( is_priv && blinding_needed &&
+        ( mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    /* It wouldn't lead to an error if it wasn't satisfied,
+     * but check for QP >= 1 nonetheless. */
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    if( is_priv &&
+        mbedcrypto_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    return( 0 );
+}
+
+int mbedcrypto_rsa_complete( mbedcrypto_rsa_context *ctx )
+{
+    int ret = 0;
+
+    const int have_N = ( mbedcrypto_mpi_cmp_int( &ctx->N, 0 ) != 0 );
+    const int have_P = ( mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) != 0 );
+    const int have_Q = ( mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
+    const int have_D = ( mbedcrypto_mpi_cmp_int( &ctx->D, 0 ) != 0 );
+    const int have_E = ( mbedcrypto_mpi_cmp_int( &ctx->E, 0 ) != 0 );
+
+    /*
+     * Check whether provided parameters are enough
+     * to deduce all others. The following incomplete
+     * parameter sets for private keys are supported:
+     *
+     * (1) P, Q missing.
+     * (2) D and potentially N missing.
+     *
+     */
+
+    const int n_missing  =              have_P &&  have_Q &&  have_D && have_E;
+    const int pq_missing =   have_N && !have_P && !have_Q &&  have_D && have_E;
+    const int d_missing  =              have_P &&  have_Q && !have_D && have_E;
+    const int is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
+
+    /* These three alternatives are mutually exclusive */
+    const int is_priv = n_missing || pq_missing || d_missing;
+
+    if( !is_priv && !is_pub )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Step 1: Deduce N if P, Q are provided.
+     */
+
+    if( !have_N && have_P && have_Q )
+    {
+        if( ( ret = mbedcrypto_mpi_mul_mpi( &ctx->N, &ctx->P,
+                                         &ctx->Q ) ) != 0 )
+        {
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        ctx->len = mbedcrypto_mpi_size( &ctx->N );
+    }
+
+    /*
+     * Step 2: Deduce and verify all remaining core parameters.
+     */
+
+    if( pq_missing )
+    {
+        ret = mbedcrypto_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
+                                         &ctx->P, &ctx->Q );
+        if( ret != 0 )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    }
+    else if( d_missing )
+    {
+        if( ( ret = mbedcrypto_rsa_deduce_private_exponent( &ctx->P,
+                                                         &ctx->Q,
+                                                         &ctx->E,
+                                                         &ctx->D ) ) != 0 )
+        {
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+    }
+
+    /*
+     * Step 3: Deduce all additional parameters specific
+     *         to our current RSA implementation.
+     */
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    if( is_priv )
+    {
+        ret = mbedcrypto_rsa_deduce_crt( &ctx->P,  &ctx->Q,  &ctx->D,
+                                      &ctx->DP, &ctx->DQ, &ctx->QP );
+        if( ret != 0 )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+    /*
+     * Step 3: Basic sanity checks
+     */
+
+    return( rsa_check_context( ctx, is_priv, 1 ) );
+}
+
+int mbedcrypto_rsa_export_raw( const mbedcrypto_rsa_context *ctx,
+                            unsigned char *N, size_t N_len,
+                            unsigned char *P, size_t P_len,
+                            unsigned char *Q, size_t Q_len,
+                            unsigned char *D, size_t D_len,
+                            unsigned char *E, size_t E_len )
+{
+    int ret = 0;
+
+    /* Check if key is private or public */
+    const int is_priv =
+        mbedcrypto_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    if( N != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &ctx->N, N, N_len ) );
+
+    if( P != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    return( ret );
+}
+
+int mbedcrypto_rsa_export( const mbedcrypto_rsa_context *ctx,
+                        mbedcrypto_mpi *N, mbedcrypto_mpi *P, mbedcrypto_mpi *Q,
+                        mbedcrypto_mpi *D, mbedcrypto_mpi *E )
+{
+    int ret;
+
+    /* Check if key is private or public */
+    int is_priv =
+        mbedcrypto_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    /* Export all requested core parameters. */
+
+    if( ( N != NULL && ( ret = mbedcrypto_mpi_copy( N, &ctx->N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedcrypto_mpi_copy( P, &ctx->P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedcrypto_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedcrypto_mpi_copy( D, &ctx->D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedcrypto_mpi_copy( E, &ctx->E ) ) != 0 ) )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Export CRT parameters
+ * This must also be implemented if CRT is not used, for being able to
+ * write DER encoded RSA keys. The helper function mbedcrypto_rsa_deduce_crt
+ * can be used in this case.
+ */
+int mbedcrypto_rsa_export_crt( const mbedcrypto_rsa_context *ctx,
+                            mbedcrypto_mpi *DP, mbedcrypto_mpi *DQ, mbedcrypto_mpi *QP )
+{
+    int ret;
+
+    /* Check if key is private or public */
+    int is_priv =
+        mbedcrypto_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedcrypto_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    /* Export all requested blinding parameters. */
+    if( ( DP != NULL && ( ret = mbedcrypto_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
+        ( DQ != NULL && ( ret = mbedcrypto_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
+        ( QP != NULL && ( ret = mbedcrypto_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#else
+    if( ( ret = mbedcrypto_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                        DP, DQ, QP ) ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Initialize an RSA context
+ */
+void mbedcrypto_rsa_init( mbedcrypto_rsa_context *ctx,
+               int padding,
+               int hash_id )
+{
+    memset( ctx, 0, sizeof( mbedcrypto_rsa_context ) );
+
+    mbedcrypto_rsa_set_padding( ctx, padding, hash_id );
+
+#if defined(MBEDCRYPTO_THREADING_C)
+    mbedcrypto_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * Set padding for an existing RSA context
+ */
+void mbedcrypto_rsa_set_padding( mbedcrypto_rsa_context *ctx, int padding, int hash_id )
+{
+    ctx->padding = padding;
+    ctx->hash_id = hash_id;
+}
+
+/*
+ * Get length in bytes of RSA modulus
+ */
+size_t mbedcrypto_rsa_get_len( const mbedcrypto_rsa_context *ctx )
+{
+    return( ctx->len );
+}
+
+/*
+ * Get length in bits of RSA modulus
+ */
+size_t mbedcrypto_rsa_get_bitlen( const mbedcrypto_rsa_context *ctx )
+{
+    return( mbedcrypto_mpi_bitlen( &ctx->N ) );
+}
+
+
+#if defined(MBEDCRYPTO_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ *
+ * This generation method follows the RSA key pair generation procedure of
+ * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
+ */
+int mbedcrypto_rsa_gen_key( mbedcrypto_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 unsigned int nbits, int exponent )
+{
+    int ret;
+    mbedcrypto_mpi H, G, L;
+
+    if( f_rng == NULL || nbits < 128 || exponent < 3 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    if( nbits % 2 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    mbedcrypto_mpi_init( &H );
+    mbedcrypto_mpi_init( &G );
+    mbedcrypto_mpi_init( &L );
+
+    /*
+     * find primes P and Q with Q < P so that:
+     * 1.  |P-Q| > 2^( nbits / 2 - 100 )
+     * 2.  GCD( E, (P-1)*(Q-1) ) == 1
+     * 3.  E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
+     */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_lset( &ctx->E, exponent ) );
+
+    do
+    {
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
+                                                f_rng, p_rng ) );
+
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
+                                                f_rng, p_rng ) );
+
+        /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
+        if( mbedcrypto_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
+            continue;
+
+        /* not required by any standards, but some users rely on the fact that P > Q */
+        if( H.s < 0 )
+            mbedcrypto_mpi_swap( &ctx->P, &ctx->Q );
+
+        /* Temporarily replace P,Q by P-1, Q-1 */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
+
+        /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_gcd( &G, &ctx->E, &H  ) );
+        if( mbedcrypto_mpi_cmp_int( &G, 1 ) != 0 )
+            continue;
+
+        /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_div_mpi( &L, NULL, &H, &G ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
+
+        if( mbedcrypto_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
+            continue;
+
+        break;
+    }
+    while( 1 );
+
+    /* Restore P,Q */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_int( &ctx->P,  &ctx->P, 1 ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_int( &ctx->Q,  &ctx->Q, 1 ) );
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+
+    ctx->len = mbedcrypto_mpi_size( &ctx->N );
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    /*
+     * DP = D mod (P - 1)
+     * DQ = D mod (Q - 1)
+     * QP = Q^-1 mod P
+     */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                             &ctx->DP, &ctx->DQ, &ctx->QP ) );
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+    /* Double-check */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_check_privkey( ctx ) );
+
+cleanup:
+
+    mbedcrypto_mpi_free( &H );
+    mbedcrypto_mpi_free( &G );
+    mbedcrypto_mpi_free( &L );
+
+    if( ret != 0 )
+    {
+        mbedcrypto_rsa_free( ctx );
+        return( MBEDCRYPTO_ERR_RSA_KEY_GEN_FAILED + ret );
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDCRYPTO_GENPRIME */
+
+/*
+ * Check a public RSA key
+ */
+int mbedcrypto_rsa_check_pubkey( const mbedcrypto_rsa_context *ctx )
+{
+    if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( mbedcrypto_mpi_bitlen( &ctx->N ) < 128 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedcrypto_mpi_get_bit( &ctx->E, 0 ) == 0 ||
+        mbedcrypto_mpi_bitlen( &ctx->E )     < 2  ||
+        mbedcrypto_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Check for the consistency of all fields in an RSA private key context
+ */
+int mbedcrypto_rsa_check_privkey( const mbedcrypto_rsa_context *ctx )
+{
+    if( mbedcrypto_rsa_check_pubkey( ctx ) != 0 ||
+        rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedcrypto_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
+                                     &ctx->D, &ctx->E, NULL, NULL ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    else if( mbedcrypto_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                       &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Check if contexts holding a public and private key match
+ */
+int mbedcrypto_rsa_check_pub_priv( const mbedcrypto_rsa_context *pub,
+                                const mbedcrypto_rsa_context *prv )
+{
+    if( mbedcrypto_rsa_check_pubkey( pub )  != 0 ||
+        mbedcrypto_rsa_check_privkey( prv ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedcrypto_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
+        mbedcrypto_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Do an RSA public key operation
+ */
+int mbedcrypto_rsa_public( mbedcrypto_rsa_context *ctx,
+                const unsigned char *input,
+                unsigned char *output )
+{
+    int ret;
+    size_t olen;
+    mbedcrypto_mpi T;
+
+    if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    mbedcrypto_mpi_init( &T );
+
+#if defined(MBEDCRYPTO_THREADING_C)
+    if( ( ret = mbedcrypto_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &T, input, ctx->len ) );
+
+    if( mbedcrypto_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        ret = MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+#if defined(MBEDCRYPTO_THREADING_C)
+    if( mbedcrypto_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDCRYPTO_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    mbedcrypto_mpi_free( &T );
+
+    if( ret != 0 )
+        return( MBEDCRYPTO_ERR_RSA_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Generate or update blinding values, see section 10 of:
+ *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
+ *  DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
+ *  Berlin Heidelberg, 1996. p. 104-113.
+ */
+static int rsa_prepare_blinding( mbedcrypto_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret, count = 0;
+
+    if( ctx->Vf.p != NULL )
+    {
+        /* We already have blinding values, just update them by squaring */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
+
+        goto cleanup;
+    }
+
+    /* Unblinding value: Vf = random number, invertible mod N */
+    do {
+        if( count++ > 10 )
+            return( MBEDCRYPTO_ERR_RSA_RNG_FAILED );
+
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    } while( mbedcrypto_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
+
+    /* Blinding value: Vi =  Vf^(-e) mod N */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
+
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Exponent blinding supposed to prevent side-channel attacks using multiple
+ * traces of measurements to recover the RSA key. The more collisions are there,
+ * the more bits of the key can be recovered. See [3].
+ *
+ * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
+ * observations on avarage.
+ *
+ * For example with 28 byte blinding to achieve 2 collisions the adversary has
+ * to make 2^112 observations on avarage.
+ *
+ * (With the currently (as of 2017 April) known best algorithms breaking 2048
+ * bit RSA requires approximately as much time as trying out 2^112 random keys.
+ * Thus in this sense with 28 byte blinding the security is not reduced by
+ * side-channel attacks like the one in [3])
+ *
+ * This countermeasure does not help if the key recovery is possible with a
+ * single trace.
+ */
+#define RSA_EXPONENT_BLINDING 28
+
+/*
+ * Do an RSA private key operation
+ */
+int mbedcrypto_rsa_private( mbedcrypto_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 const unsigned char *input,
+                 unsigned char *output )
+{
+    int ret;
+    size_t olen;
+
+    /* Temporary holding the result */
+    mbedcrypto_mpi T;
+
+    /* Temporaries holding P-1, Q-1 and the
+     * exponent blinding factor, respectively. */
+    mbedcrypto_mpi P1, Q1, R;
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    /* Temporaries holding the results mod p resp. mod q. */
+    mbedcrypto_mpi TP, TQ;
+
+    /* Temporaries holding the blinded exponents for
+     * the mod p resp. mod q computation (if used). */
+    mbedcrypto_mpi DP_blind, DQ_blind;
+
+    /* Pointers to actual exponents to be used - either the unblinded
+     * or the blinded ones, depending on the presence of a PRNG. */
+    mbedcrypto_mpi *DP = &ctx->DP;
+    mbedcrypto_mpi *DQ = &ctx->DQ;
+#else
+    /* Temporary holding the blinded exponent (if used). */
+    mbedcrypto_mpi D_blind;
+
+    /* Pointer to actual exponent to be used - either the unblinded
+     * or the blinded one, depending on the presence of a PRNG. */
+    mbedcrypto_mpi *D = &ctx->D;
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+    /* Temporaries holding the initial input and the double
+     * checked result; should be the same in the end. */
+    mbedcrypto_mpi I, C;
+
+    if( rsa_check_context( ctx, 1             /* private key checks */,
+                                f_rng != NULL /* blinding y/n       */ ) != 0 )
+    {
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDCRYPTO_THREADING_C)
+    if( ( ret = mbedcrypto_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    /* MPI Initialization */
+    mbedcrypto_mpi_init( &T );
+
+    mbedcrypto_mpi_init( &P1 );
+    mbedcrypto_mpi_init( &Q1 );
+    mbedcrypto_mpi_init( &R );
+
+    if( f_rng != NULL )
+    {
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+        mbedcrypto_mpi_init( &D_blind );
+#else
+        mbedcrypto_mpi_init( &DP_blind );
+        mbedcrypto_mpi_init( &DQ_blind );
+#endif
+    }
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    mbedcrypto_mpi_init( &TP ); mbedcrypto_mpi_init( &TQ );
+#endif
+
+    mbedcrypto_mpi_init( &I );
+    mbedcrypto_mpi_init( &C );
+
+    /* End of MPI initialization */
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_binary( &T, input, ctx->len ) );
+    if( mbedcrypto_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        ret = MBEDCRYPTO_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &I, &T ) );
+
+    if( f_rng != NULL )
+    {
+        /*
+         * Blinding
+         * T = T * Vi mod N
+         */
+        MBEDCRYPTO_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mod_mpi( &T, &T, &ctx->N ) );
+
+        /*
+         * Exponent blinding
+         */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_int( &P1, &ctx->P, 1 ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+        /*
+         * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
+         */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
+
+        D = &D_blind;
+#else
+        /*
+         * DP_blind = ( P - 1 ) * R + DP
+         */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &DP_blind, &P1, &R ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_mpi( &DP_blind, &DP_blind,
+                    &ctx->DP ) );
+
+        DP = &DP_blind;
+
+        /*
+         * DQ_blind = ( Q - 1 ) * R + DQ
+         */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_mpi( &DQ_blind, &DQ_blind,
+                    &ctx->DQ ) );
+
+        DQ = &DQ_blind;
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+    }
+
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
+#else
+    /*
+     * Faster decryption using the CRT
+     *
+     * TP = input ^ dP mod P
+     * TQ = input ^ dQ mod Q
+     */
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
+
+    /*
+     * T = (TP - TQ) * (Q^-1 mod P) mod P
+     */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_sub_mpi( &T, &TP, &TQ ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mod_mpi( &T, &TP, &ctx->P ) );
+
+    /*
+     * T = TQ + T * Q
+     */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_add_mpi( &T, &TQ, &TP ) );
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+    if( f_rng != NULL )
+    {
+        /*
+         * Unblind
+         * T = T * Vf mod N
+         */
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
+        MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_mod_mpi( &T, &T, &ctx->N ) );
+    }
+
+    /* Verify the result to prevent glitching attacks. */
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_exp_mod( &C, &T, &ctx->E,
+                                          &ctx->N, &ctx->RN ) );
+    if( mbedcrypto_mpi_cmp_mpi( &C, &I ) != 0 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+#if defined(MBEDCRYPTO_THREADING_C)
+    if( mbedcrypto_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDCRYPTO_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    mbedcrypto_mpi_free( &P1 );
+    mbedcrypto_mpi_free( &Q1 );
+    mbedcrypto_mpi_free( &R );
+
+    if( f_rng != NULL )
+    {
+#if defined(MBEDCRYPTO_RSA_NO_CRT)
+        mbedcrypto_mpi_free( &D_blind );
+#else
+        mbedcrypto_mpi_free( &DP_blind );
+        mbedcrypto_mpi_free( &DQ_blind );
+#endif
+    }
+
+    mbedcrypto_mpi_free( &T );
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    mbedcrypto_mpi_free( &TP ); mbedcrypto_mpi_free( &TQ );
+#endif
+
+    mbedcrypto_mpi_free( &C );
+    mbedcrypto_mpi_free( &I );
+
+    if( ret != 0 )
+        return( MBEDCRYPTO_ERR_RSA_PRIVATE_FAILED + ret );
+
+    return( 0 );
+}
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+/**
+ * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
+ *
+ * \param dst       buffer to mask
+ * \param dlen      length of destination buffer
+ * \param src       source of the mask generation
+ * \param slen      length of the source buffer
+ * \param md_ctx    message digest context to use
+ */
+static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
+                      size_t slen, mbedcrypto_md_context_t *md_ctx )
+{
+    unsigned char mask[MBEDCRYPTO_MD_MAX_SIZE];
+    unsigned char counter[4];
+    unsigned char *p;
+    unsigned int hlen;
+    size_t i, use_len;
+    int ret = 0;
+
+    memset( mask, 0, MBEDCRYPTO_MD_MAX_SIZE );
+    memset( counter, 0, 4 );
+
+    hlen = mbedcrypto_md_get_size( md_ctx->md_info );
+
+    /* Generate and apply dbMask */
+    p = dst;
+
+    while( dlen > 0 )
+    {
+        use_len = hlen;
+        if( dlen < hlen )
+            use_len = dlen;
+
+        if( ( ret = mbedcrypto_md_starts( md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedcrypto_md_update( md_ctx, src, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedcrypto_md_update( md_ctx, counter, 4 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedcrypto_md_finish( md_ctx, mask ) ) != 0 )
+            goto exit;
+
+        for( i = 0; i < use_len; ++i )
+            *p++ ^= mask[i];
+
+        counter[3]++;
+
+        dlen -= use_len;
+    }
+
+exit:
+    mbedcrypto_platform_zeroize( mask, sizeof( mask ) );
+
+    return( ret );
+}
+#endif /* MBEDCRYPTO_PKCS1_V21 */
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
+ */
+int mbedcrypto_rsa_rsaes_oaep_encrypt( mbedcrypto_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t ilen,
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    size_t olen;
+    int ret;
+    unsigned char *p = output;
+    unsigned int hlen;
+    const mbedcrypto_md_info_t *md_info;
+    mbedcrypto_md_context_t md_ctx;
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V21 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    if( f_rng == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = mbedcrypto_md_info_from_type( (mbedcrypto_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+    hlen = mbedcrypto_md_get_size( md_info );
+
+    /* first comparison checks for overflow */
+    if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    memset( output, 0, olen );
+
+    *p++ = 0;
+
+    /* Generate a random octet string seed */
+    if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
+        return( MBEDCRYPTO_ERR_RSA_RNG_FAILED + ret );
+
+    p += hlen;
+
+    /* Construct DB */
+    if( ( ret = mbedcrypto_md( md_info, label, label_len, p ) ) != 0 )
+        return( ret );
+    p += hlen;
+    p += olen - 2 * hlen - 2 - ilen;
+    *p++ = 1;
+    if( ilen != 0 )
+        memcpy( p, input, ilen );
+
+    mbedcrypto_md_init( &md_ctx );
+    if( ( ret = mbedcrypto_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    /* maskedDB: Apply dbMask to DB */
+    if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+    /* maskedSeed: Apply seedMask to seed */
+    if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedcrypto_md_free( &md_ctx );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( ( mode == MBEDCRYPTO_RSA_PUBLIC )
+            ? mbedcrypto_rsa_public(  ctx, output, output )
+            : mbedcrypto_rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* MBEDCRYPTO_PKCS1_V21 */
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
+ */
+int mbedcrypto_rsa_rsaes_pkcs1_v15_encrypt( mbedcrypto_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t ilen,
+                                 const unsigned char *input,
+                                 unsigned char *output )
+{
+    size_t nb_pad, olen;
+    int ret;
+    unsigned char *p = output;
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V15 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    // We don't check p_rng because it won't be dereferenced here
+    if( f_rng == NULL || output == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    if( ilen != 0 && input == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    /* first comparison checks for overflow */
+    if( ilen + 11 < ilen || olen < ilen + 11 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    nb_pad = olen - 3 - ilen;
+
+    *p++ = 0;
+    if( mode == MBEDCRYPTO_RSA_PUBLIC )
+    {
+        *p++ = MBEDCRYPTO_RSA_CRYPT;
+
+        while( nb_pad-- > 0 )
+        {
+            int rng_dl = 100;
+
+            do {
+                ret = f_rng( p_rng, p, 1 );
+            } while( *p == 0 && --rng_dl && ret == 0 );
+
+            /* Check if RNG failed to generate data */
+            if( rng_dl == 0 || ret != 0 )
+                return( MBEDCRYPTO_ERR_RSA_RNG_FAILED + ret );
+
+            p++;
+        }
+    }
+    else
+    {
+        *p++ = MBEDCRYPTO_RSA_SIGN;
+
+        while( nb_pad-- > 0 )
+            *p++ = 0xFF;
+    }
+
+    *p++ = 0;
+    if( ilen != 0 )
+        memcpy( p, input, ilen );
+
+    return( ( mode == MBEDCRYPTO_RSA_PUBLIC )
+            ? mbedcrypto_rsa_public(  ctx, output, output )
+            : mbedcrypto_rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int mbedcrypto_rsa_pkcs1_encrypt( mbedcrypto_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t ilen,
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    switch( ctx->padding )
+    {
+#if defined(MBEDCRYPTO_PKCS1_V15)
+        case MBEDCRYPTO_RSA_PKCS_V15:
+            return mbedcrypto_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
+                                                input, output );
+#endif
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+        case MBEDCRYPTO_RSA_PKCS_V21:
+            return mbedcrypto_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           ilen, input, output );
+#endif
+
+        default:
+            return( MBEDCRYPTO_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
+ */
+int mbedcrypto_rsa_rsaes_oaep_decrypt( mbedcrypto_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t *olen,
+                            const unsigned char *input,
+                            unsigned char *output,
+                            size_t output_max_len )
+{
+    int ret;
+    size_t ilen, i, pad_len;
+    unsigned char *p, bad, pad_done;
+    unsigned char buf[MBEDCRYPTO_MPI_MAX_SIZE];
+    unsigned char lhash[MBEDCRYPTO_MD_MAX_SIZE];
+    unsigned int hlen;
+    const mbedcrypto_md_info_t *md_info;
+    mbedcrypto_md_context_t md_ctx;
+
+    /*
+     * Parameters sanity checks
+     */
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V21 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    ilen = ctx->len;
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = mbedcrypto_md_info_from_type( (mbedcrypto_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedcrypto_md_get_size( md_info );
+
+    // checking for integer underflow
+    if( 2 * hlen + 2 > ilen )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * RSA operation
+     */
+    ret = ( mode == MBEDCRYPTO_RSA_PUBLIC )
+          ? mbedcrypto_rsa_public(  ctx, input, buf )
+          : mbedcrypto_rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        goto cleanup;
+
+    /*
+     * Unmask data and generate lHash
+     */
+    mbedcrypto_md_init( &md_ctx );
+    if( ( ret = mbedcrypto_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedcrypto_md_free( &md_ctx );
+        goto cleanup;
+    }
+
+    /* seed: Apply seedMask to maskedSeed */
+    if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
+                          &md_ctx ) ) != 0 ||
+    /* DB: Apply dbMask to maskedDB */
+        ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
+                          &md_ctx ) ) != 0 )
+    {
+        mbedcrypto_md_free( &md_ctx );
+        goto cleanup;
+    }
+
+    mbedcrypto_md_free( &md_ctx );
+
+    /* Generate lHash */
+    if( ( ret = mbedcrypto_md( md_info, label, label_len, lhash ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * Check contents, in "constant-time"
+     */
+    p = buf;
+    bad = 0;
+
+    bad |= *p++; /* First byte must be 0 */
+
+    p += hlen; /* Skip seed */
+
+    /* Check lHash */
+    for( i = 0; i < hlen; i++ )
+        bad |= lhash[i] ^ *p++;
+
+    /* Get zero-padding len, but always read till end of buffer
+     * (minus one, for the 01 byte) */
+    pad_len = 0;
+    pad_done = 0;
+    for( i = 0; i < ilen - 2 * hlen - 2; i++ )
+    {
+        pad_done |= p[i];
+        pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+    }
+
+    p += pad_len;
+    bad |= *p++ ^ 0x01;
+
+    /*
+     * The only information "leaked" is whether the padding was correct or not
+     * (eg, no data is copied if it was not correct). This meets the
+     * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
+     * the different error conditions.
+     */
+    if( bad != 0 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_INVALID_PADDING;
+        goto cleanup;
+    }
+
+    if( ilen - ( p - buf ) > output_max_len )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE;
+        goto cleanup;
+    }
+
+    *olen = ilen - (p - buf);
+    if( *olen != 0 )
+        memcpy( output, p, *olen );
+    ret = 0;
+
+cleanup:
+    mbedcrypto_platform_zeroize( buf, sizeof( buf ) );
+    mbedcrypto_platform_zeroize( lhash, sizeof( lhash ) );
+
+    return( ret );
+}
+#endif /* MBEDCRYPTO_PKCS1_V21 */
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
+ */
+int mbedcrypto_rsa_rsaes_pkcs1_v15_decrypt( mbedcrypto_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t *olen,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 size_t output_max_len)
+{
+    int ret;
+    size_t ilen, pad_count = 0, i;
+    unsigned char *p, bad, pad_done = 0;
+    unsigned char buf[MBEDCRYPTO_MPI_MAX_SIZE];
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V15 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    ilen = ctx->len;
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == MBEDCRYPTO_RSA_PUBLIC )
+          ? mbedcrypto_rsa_public(  ctx, input, buf )
+          : mbedcrypto_rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        goto cleanup;
+
+    p = buf;
+    bad = 0;
+
+    /*
+     * Check and get padding len in "constant-time"
+     */
+    bad |= *p++; /* First byte must be 0 */
+
+    /* This test does not depend on secret data */
+    if( mode == MBEDCRYPTO_RSA_PRIVATE )
+    {
+        bad |= *p++ ^ MBEDCRYPTO_RSA_CRYPT;
+
+        /* Get padding len, but always read till end of buffer
+         * (minus one, for the 00 byte) */
+        for( i = 0; i < ilen - 3; i++ )
+        {
+            pad_done  |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
+            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+        }
+
+        p += pad_count;
+        bad |= *p++; /* Must be zero */
+    }
+    else
+    {
+        bad |= *p++ ^ MBEDCRYPTO_RSA_SIGN;
+
+        /* Get padding len, but always read till end of buffer
+         * (minus one, for the 00 byte) */
+        for( i = 0; i < ilen - 3; i++ )
+        {
+            pad_done |= ( p[i] != 0xFF );
+            pad_count += ( pad_done == 0 );
+        }
+
+        p += pad_count;
+        bad |= *p++; /* Must be zero */
+    }
+
+    bad |= ( pad_count < 8 );
+
+    if( bad )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_INVALID_PADDING;
+        goto cleanup;
+    }
+
+    if( ilen - ( p - buf ) > output_max_len )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_OUTPUT_TOO_LARGE;
+        goto cleanup;
+    }
+
+    *olen = ilen - (p - buf);
+    if( *olen != 0 )
+        memcpy( output, p, *olen );
+    ret = 0;
+
+cleanup:
+    mbedcrypto_platform_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
+}
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int mbedcrypto_rsa_pkcs1_decrypt( mbedcrypto_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len)
+{
+    switch( ctx->padding )
+    {
+#if defined(MBEDCRYPTO_PKCS1_V15)
+        case MBEDCRYPTO_RSA_PKCS_V15:
+            return mbedcrypto_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
+                                                input, output, output_max_len );
+#endif
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+        case MBEDCRYPTO_RSA_PKCS_V21:
+            return mbedcrypto_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           olen, input, output,
+                                           output_max_len );
+#endif
+
+        default:
+            return( MBEDCRYPTO_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedcrypto_rsa_rsassa_pss_sign( mbedcrypto_rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         int mode,
+                         mbedcrypto_md_type_t md_alg,
+                         unsigned int hashlen,
+                         const unsigned char *hash,
+                         unsigned char *sig )
+{
+    size_t olen;
+    unsigned char *p = sig;
+    unsigned char salt[MBEDCRYPTO_MD_MAX_SIZE];
+    unsigned int slen, hlen, offset = 0;
+    int ret;
+    size_t msb;
+    const mbedcrypto_md_info_t *md_info;
+    mbedcrypto_md_context_t md_ctx;
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V21 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    if( f_rng == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    if( md_alg != MBEDCRYPTO_MD_NONE )
+    {
+        /* Gather length of hash to sign */
+        md_info = mbedcrypto_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedcrypto_md_get_size( md_info );
+    }
+
+    md_info = mbedcrypto_md_info_from_type( (mbedcrypto_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedcrypto_md_get_size( md_info );
+    slen = hlen;
+
+    if( olen < hlen + slen + 2 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    memset( sig, 0, olen );
+
+    /* Generate salt of length slen */
+    if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+        return( MBEDCRYPTO_ERR_RSA_RNG_FAILED + ret );
+
+    /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
+    msb = mbedcrypto_mpi_bitlen( &ctx->N ) - 1;
+    p += olen - hlen * 2 - 2;
+    *p++ = 0x01;
+    memcpy( p, salt, slen );
+    p += slen;
+
+    mbedcrypto_md_init( &md_ctx );
+    if( ( ret = mbedcrypto_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    /* Generate H = Hash( M' ) */
+    if( ( ret = mbedcrypto_md_starts( &md_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedcrypto_md_update( &md_ctx, p, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedcrypto_md_update( &md_ctx, hash, hashlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedcrypto_md_update( &md_ctx, salt, slen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedcrypto_md_finish( &md_ctx, p ) ) != 0 )
+        goto exit;
+
+    /* Compensate for boundary condition when applying mask */
+    if( msb % 8 == 0 )
+        offset = 1;
+
+    /* maskedDB: Apply dbMask to DB */
+    if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+    msb = mbedcrypto_mpi_bitlen( &ctx->N ) - 1;
+    sig[0] &= 0xFF >> ( olen * 8 - msb );
+
+    p += hlen;
+    *p++ = 0xBC;
+
+    mbedcrypto_platform_zeroize( salt, sizeof( salt ) );
+
+exit:
+    mbedcrypto_md_free( &md_ctx );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( ( mode == MBEDCRYPTO_RSA_PUBLIC )
+            ? mbedcrypto_rsa_public(  ctx, sig, sig )
+            : mbedcrypto_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
+}
+#endif /* MBEDCRYPTO_PKCS1_V21 */
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
+ */
+
+/* Construct a PKCS v1.5 encoding of a hashed message
+ *
+ * This is used both for signature generation and verification.
+ *
+ * Parameters:
+ * - md_alg:  Identifies the hash algorithm used to generate the given hash;
+ *            MBEDCRYPTO_MD_NONE if raw data is signed.
+ * - hashlen: Length of hash in case hashlen is MBEDCRYPTO_MD_NONE.
+ * - hash:    Buffer containing the hashed message or the raw data.
+ * - dst_len: Length of the encoded message.
+ * - dst:     Buffer to hold the encoded message.
+ *
+ * Assumptions:
+ * - hash has size hashlen if md_alg == MBEDCRYPTO_MD_NONE.
+ * - hash has size corresponding to md_alg if md_alg != MBEDCRYPTO_MD_NONE.
+ * - dst points to a buffer of size at least dst_len.
+ *
+ */
+static int rsa_rsassa_pkcs1_v15_encode( mbedcrypto_md_type_t md_alg,
+                                        unsigned int hashlen,
+                                        const unsigned char *hash,
+                                        size_t dst_len,
+                                        unsigned char *dst )
+{
+    size_t oid_size  = 0;
+    size_t nb_pad    = dst_len;
+    unsigned char *p = dst;
+    const char *oid  = NULL;
+
+    /* Are we signing hashed or raw data? */
+    if( md_alg != MBEDCRYPTO_MD_NONE )
+    {
+        const mbedcrypto_md_info_t *md_info = mbedcrypto_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        if( mbedcrypto_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedcrypto_md_get_size( md_info );
+
+        /* Double-check that 8 + hashlen + oid_size can be used as a
+         * 1-byte ASN.1 length encoding and that there's no overflow. */
+        if( 8 + hashlen + oid_size  >= 0x80         ||
+            10 + hashlen            <  hashlen      ||
+            10 + hashlen + oid_size <  10 + hashlen )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        /*
+         * Static bounds check:
+         * - Need 10 bytes for five tag-length pairs.
+         *   (Insist on 1-byte length encodings to protect against variants of
+         *    Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
+         * - Need hashlen bytes for hash
+         * - Need oid_size bytes for hash alg OID.
+         */
+        if( nb_pad < 10 + hashlen + oid_size )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+        nb_pad -= 10 + hashlen + oid_size;
+    }
+    else
+    {
+        if( nb_pad < hashlen )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        nb_pad -= hashlen;
+    }
+
+    /* Need space for signature header and padding delimiter (3 bytes),
+     * and 8 bytes for the minimal padding */
+    if( nb_pad < 3 + 8 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    nb_pad -= 3;
+
+    /* Now nb_pad is the amount of memory to be filled
+     * with padding, and at least 8 bytes long. */
+
+    /* Write signature header and padding */
+    *p++ = 0;
+    *p++ = MBEDCRYPTO_RSA_SIGN;
+    memset( p, 0xFF, nb_pad );
+    p += nb_pad;
+    *p++ = 0;
+
+    /* Are we signing raw data? */
+    if( md_alg == MBEDCRYPTO_MD_NONE )
+    {
+        memcpy( p, hash, hashlen );
+        return( 0 );
+    }
+
+    /* Signing hashed data, add corresponding ASN.1 structure
+     *
+     * DigestInfo ::= SEQUENCE {
+     *   digestAlgorithm DigestAlgorithmIdentifier,
+     *   digest Digest }
+     * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+     * Digest ::= OCTET STRING
+     *
+     * Schematic:
+     * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID  + LEN [ OID  ]
+     *                                 TAG-NULL + LEN [ NULL ] ]
+     *                 TAG-OCTET + LEN [ HASH ] ]
+     */
+    *p++ = MBEDCRYPTO_ASN1_SEQUENCE | MBEDCRYPTO_ASN1_CONSTRUCTED;
+    *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
+    *p++ = MBEDCRYPTO_ASN1_SEQUENCE | MBEDCRYPTO_ASN1_CONSTRUCTED;
+    *p++ = (unsigned char)( 0x04 + oid_size );
+    *p++ = MBEDCRYPTO_ASN1_OID;
+    *p++ = (unsigned char) oid_size;
+    memcpy( p, oid, oid_size );
+    p += oid_size;
+    *p++ = MBEDCRYPTO_ASN1_NULL;
+    *p++ = 0x00;
+    *p++ = MBEDCRYPTO_ASN1_OCTET_STRING;
+    *p++ = (unsigned char) hashlen;
+    memcpy( p, hash, hashlen );
+    p += hashlen;
+
+    /* Just a sanity-check, should be automatic
+     * after the initial bounds check. */
+    if( p != dst + dst_len )
+    {
+        mbedcrypto_platform_zeroize( dst, dst_len );
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedcrypto_rsa_rsassa_pkcs1_v15_sign( mbedcrypto_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedcrypto_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               unsigned char *sig )
+{
+    int ret;
+    unsigned char *sig_try = NULL, *verif = NULL;
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V15 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
+     */
+
+    if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
+                                             ctx->len, sig ) ) != 0 )
+        return( ret );
+
+    /*
+     * Call respective RSA primitive
+     */
+
+    if( mode == MBEDCRYPTO_RSA_PUBLIC )
+    {
+        /* Skip verification on a public key operation */
+        return( mbedcrypto_rsa_public( ctx, sig, sig ) );
+    }
+
+    /* Private key operation
+     *
+     * In order to prevent Lenstra's attack, make the signature in a
+     * temporary buffer and check it before returning it.
+     */
+
+    sig_try = mbedcrypto_calloc( 1, ctx->len );
+    if( sig_try == NULL )
+        return( MBEDCRYPTO_ERR_MPI_ALLOC_FAILED );
+
+    verif = mbedcrypto_calloc( 1, ctx->len );
+    if( verif == NULL )
+    {
+        mbedcrypto_free( sig_try );
+        return( MBEDCRYPTO_ERR_MPI_ALLOC_FAILED );
+    }
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_public( ctx, sig_try, verif ) );
+
+    if( mbedcrypto_safer_memcmp( verif, sig, ctx->len ) != 0 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_PRIVATE_FAILED;
+        goto cleanup;
+    }
+
+    memcpy( sig, sig_try, ctx->len );
+
+cleanup:
+    mbedcrypto_free( sig_try );
+    mbedcrypto_free( verif );
+
+    return( ret );
+}
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedcrypto_rsa_pkcs1_sign( mbedcrypto_rsa_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    int mode,
+                    mbedcrypto_md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig )
+{
+    switch( ctx->padding )
+    {
+#if defined(MBEDCRYPTO_PKCS1_V15)
+        case MBEDCRYPTO_RSA_PKCS_V15:
+            return mbedcrypto_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                              hashlen, hash, sig );
+#endif
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+        case MBEDCRYPTO_RSA_PKCS_V21:
+            return mbedcrypto_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                        hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDCRYPTO_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedcrypto_rsa_rsassa_pss_verify_ext( mbedcrypto_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedcrypto_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               mbedcrypto_md_type_t mgf1_hash_id,
+                               int expected_salt_len,
+                               const unsigned char *sig )
+{
+    int ret;
+    size_t siglen;
+    unsigned char *p;
+    unsigned char *hash_start;
+    unsigned char result[MBEDCRYPTO_MD_MAX_SIZE];
+    unsigned char zeros[8];
+    unsigned int hlen;
+    size_t observed_salt_len, msb;
+    const mbedcrypto_md_info_t *md_info;
+    mbedcrypto_md_context_t md_ctx;
+    unsigned char buf[MBEDCRYPTO_MPI_MAX_SIZE];
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V21 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    siglen = ctx->len;
+
+    if( siglen < 16 || siglen > sizeof( buf ) )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == MBEDCRYPTO_RSA_PUBLIC )
+          ? mbedcrypto_rsa_public(  ctx, sig, buf )
+          : mbedcrypto_rsa_private( ctx, f_rng, p_rng, sig, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    p = buf;
+
+    if( buf[siglen - 1] != 0xBC )
+        return( MBEDCRYPTO_ERR_RSA_INVALID_PADDING );
+
+    if( md_alg != MBEDCRYPTO_MD_NONE )
+    {
+        /* Gather length of hash to sign */
+        md_info = mbedcrypto_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedcrypto_md_get_size( md_info );
+    }
+
+    md_info = mbedcrypto_md_info_from_type( mgf1_hash_id );
+    if( md_info == NULL )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedcrypto_md_get_size( md_info );
+
+    memset( zeros, 0, 8 );
+
+    /*
+     * Note: EMSA-PSS verification is over the length of N - 1 bits
+     */
+    msb = mbedcrypto_mpi_bitlen( &ctx->N ) - 1;
+
+    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    /* Compensate for boundary condition when applying mask */
+    if( msb % 8 == 0 )
+    {
+        p++;
+        siglen -= 1;
+    }
+
+    if( siglen < hlen + 2 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+    hash_start = p + siglen - hlen - 1;
+
+    mbedcrypto_md_init( &md_ctx );
+    if( ( ret = mbedcrypto_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
+    if( ret != 0 )
+        goto exit;
+
+    buf[0] &= 0xFF >> ( siglen * 8 - msb );
+
+    while( p < hash_start - 1 && *p == 0 )
+        p++;
+
+    if( *p++ != 0x01 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_INVALID_PADDING;
+        goto exit;
+    }
+
+    observed_salt_len = hash_start - p;
+
+    if( expected_salt_len != MBEDCRYPTO_RSA_SALT_LEN_ANY &&
+        observed_salt_len != (size_t) expected_salt_len )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_INVALID_PADDING;
+        goto exit;
+    }
+
+    /*
+     * Generate H = Hash( M' )
+     */
+    ret = mbedcrypto_md_starts( &md_ctx );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedcrypto_md_update( &md_ctx, zeros, 8 );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedcrypto_md_update( &md_ctx, hash, hashlen );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedcrypto_md_update( &md_ctx, p, observed_salt_len );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedcrypto_md_finish( &md_ctx, result );
+    if ( ret != 0 )
+        goto exit;
+
+    if( memcmp( hash_start, result, hlen ) != 0 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_VERIFY_FAILED;
+        goto exit;
+    }
+
+exit:
+    mbedcrypto_md_free( &md_ctx );
+
+    return( ret );
+}
+
+/*
+ * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedcrypto_rsa_rsassa_pss_verify( mbedcrypto_rsa_context *ctx,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           int mode,
+                           mbedcrypto_md_type_t md_alg,
+                           unsigned int hashlen,
+                           const unsigned char *hash,
+                           const unsigned char *sig )
+{
+    mbedcrypto_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDCRYPTO_MD_NONE )
+                             ? (mbedcrypto_md_type_t) ctx->hash_id
+                             : md_alg;
+
+    return( mbedcrypto_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
+                                       md_alg, hashlen, hash,
+                                       mgf1_hash_id, MBEDCRYPTO_RSA_SALT_LEN_ANY,
+                                       sig ) );
+
+}
+#endif /* MBEDCRYPTO_PKCS1_V21 */
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
+ */
+int mbedcrypto_rsa_rsassa_pkcs1_v15_verify( mbedcrypto_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode,
+                                 mbedcrypto_md_type_t md_alg,
+                                 unsigned int hashlen,
+                                 const unsigned char *hash,
+                                 const unsigned char *sig )
+{
+    int ret = 0;
+    const size_t sig_len = ctx->len;
+    unsigned char *encoded = NULL, *encoded_expected = NULL;
+
+    if( mode == MBEDCRYPTO_RSA_PRIVATE && ctx->padding != MBEDCRYPTO_RSA_PKCS_V15 )
+        return( MBEDCRYPTO_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Prepare expected PKCS1 v1.5 encoding of hash.
+     */
+
+    if( ( encoded          = mbedcrypto_calloc( 1, sig_len ) ) == NULL ||
+        ( encoded_expected = mbedcrypto_calloc( 1, sig_len ) ) == NULL )
+    {
+        ret = MBEDCRYPTO_ERR_MPI_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
+                                             encoded_expected ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * Apply RSA primitive to get what should be PKCS1 encoded hash.
+     */
+
+    ret = ( mode == MBEDCRYPTO_RSA_PUBLIC )
+          ? mbedcrypto_rsa_public(  ctx, sig, encoded )
+          : mbedcrypto_rsa_private( ctx, f_rng, p_rng, sig, encoded );
+    if( ret != 0 )
+        goto cleanup;
+
+    /*
+     * Compare
+     */
+
+    if( ( ret = mbedcrypto_safer_memcmp( encoded, encoded_expected,
+                                      sig_len ) ) != 0 )
+    {
+        ret = MBEDCRYPTO_ERR_RSA_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+cleanup:
+
+    if( encoded != NULL )
+    {
+        mbedcrypto_platform_zeroize( encoded, sig_len );
+        mbedcrypto_free( encoded );
+    }
+
+    if( encoded_expected != NULL )
+    {
+        mbedcrypto_platform_zeroize( encoded_expected, sig_len );
+        mbedcrypto_free( encoded_expected );
+    }
+
+    return( ret );
+}
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int mbedcrypto_rsa_pkcs1_verify( mbedcrypto_rsa_context *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng,
+                      int mode,
+                      mbedcrypto_md_type_t md_alg,
+                      unsigned int hashlen,
+                      const unsigned char *hash,
+                      const unsigned char *sig )
+{
+    switch( ctx->padding )
+    {
+#if defined(MBEDCRYPTO_PKCS1_V15)
+        case MBEDCRYPTO_RSA_PKCS_V15:
+            return mbedcrypto_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                                hashlen, hash, sig );
+#endif
+
+#if defined(MBEDCRYPTO_PKCS1_V21)
+        case MBEDCRYPTO_RSA_PKCS_V21:
+            return mbedcrypto_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                          hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDCRYPTO_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+/*
+ * Copy the components of an RSA key
+ */
+int mbedcrypto_rsa_copy( mbedcrypto_rsa_context *dst, const mbedcrypto_rsa_context *src )
+{
+    int ret;
+
+    dst->ver = src->ver;
+    dst->len = src->len;
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->N, &src->N ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->E, &src->E ) );
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->D, &src->D ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->P, &src->P ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->Q, &src->Q ) );
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->DP, &src->DP ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->DQ, &src->DQ ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->QP, &src->QP ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->RP, &src->RP ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->RQ, &src->RQ ) );
+#endif
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->RN, &src->RN ) );
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->Vi, &src->Vi ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_copy( &dst->Vf, &src->Vf ) );
+
+    dst->padding = src->padding;
+    dst->hash_id = src->hash_id;
+
+cleanup:
+    if( ret != 0 )
+        mbedcrypto_rsa_free( dst );
+
+    return( ret );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void mbedcrypto_rsa_free( mbedcrypto_rsa_context *ctx )
+{
+    mbedcrypto_mpi_free( &ctx->Vi ); mbedcrypto_mpi_free( &ctx->Vf );
+    mbedcrypto_mpi_free( &ctx->RN ); mbedcrypto_mpi_free( &ctx->D  );
+    mbedcrypto_mpi_free( &ctx->Q  ); mbedcrypto_mpi_free( &ctx->P  );
+    mbedcrypto_mpi_free( &ctx->E  ); mbedcrypto_mpi_free( &ctx->N  );
+
+#if !defined(MBEDCRYPTO_RSA_NO_CRT)
+    mbedcrypto_mpi_free( &ctx->RQ ); mbedcrypto_mpi_free( &ctx->RP );
+    mbedcrypto_mpi_free( &ctx->QP ); mbedcrypto_mpi_free( &ctx->DQ );
+    mbedcrypto_mpi_free( &ctx->DP );
+#endif /* MBEDCRYPTO_RSA_NO_CRT */
+
+#if defined(MBEDCRYPTO_THREADING_C)
+    mbedcrypto_mutex_free( &ctx->mutex );
+#endif
+}
+
+#endif /* !MBEDCRYPTO_RSA_ALT */
+
+#if defined(MBEDCRYPTO_SELF_TEST)
+
+#include "mbedcrypto/sha1.h"
+
+/*
+ * Example RSA-1024 keypair, for test purposes
+ */
+#define KEY_LEN 128
+
+#define RSA_N   "9292758453063D803DD603D5E777D788" \
+                "8ED1D5BF35786190FA2F23EBC0848AEA" \
+                "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
+                "7130B9CED7ACDF54CFC7555AC14EEBAB" \
+                "93A89813FBF3C4F8066D2D800F7C38A8" \
+                "1AE31942917403FF4946B0A83D3D3E05" \
+                "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
+                "5E94BB77B07507233A0BC7BAC8F90F79"
+
+#define RSA_E   "10001"
+
+#define RSA_D   "24BF6185468786FDD303083D25E64EFC" \
+                "66CA472BC44D253102F8B4A9D3BFA750" \
+                "91386C0077937FE33FA3252D28855837" \
+                "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
+                "DF79C5CE07EE72C7F123142198164234" \
+                "CABB724CF78B8173B9F880FC86322407" \
+                "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
+                "071513A1E85B5DFA031F21ECAE91A34D"
+
+#define RSA_P   "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
+                "2C01CAD19EA484A87EA4377637E75500" \
+                "FCB2005C5C7DD6EC4AC023CDA285D796" \
+                "C3D9E75E1EFC42488BB4F1D13AC30A57"
+
+#define RSA_Q   "C000DF51A7C77AE8D7C7370C1FF55B69" \
+                "E211C2B9E5DB1ED0BF61D0D9899620F4" \
+                "910E4168387E3C30AA1E00C339A79508" \
+                "8452DD96A9A5EA5D9DCA68DA636032AF"
+
+#define PT_LEN  24
+#define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
+                "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
+
+#if defined(MBEDCRYPTO_PKCS1_V15)
+static int myrand( void *rng_state, unsigned char *output, size_t len )
+{
+#if !defined(__OpenBSD__)
+    size_t i;
+
+    if( rng_state != NULL )
+        rng_state  = NULL;
+
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+#else
+    if( rng_state != NULL )
+        rng_state = NULL;
+
+    arc4random_buf( output, len );
+#endif /* !OpenBSD */
+
+    return( 0 );
+}
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+
+/*
+ * Checkup routine
+ */
+int mbedcrypto_rsa_self_test( int verbose )
+{
+    int ret = 0;
+#if defined(MBEDCRYPTO_PKCS1_V15)
+    size_t len;
+    mbedcrypto_rsa_context rsa;
+    unsigned char rsa_plaintext[PT_LEN];
+    unsigned char rsa_decrypted[PT_LEN];
+    unsigned char rsa_ciphertext[KEY_LEN];
+#if defined(MBEDCRYPTO_SHA1_C)
+    unsigned char sha1sum[20];
+#endif
+
+    mbedcrypto_mpi K;
+
+    mbedcrypto_mpi_init( &K );
+    mbedcrypto_rsa_init( &rsa, MBEDCRYPTO_RSA_PKCS_V15, 0 );
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_string( &K, 16, RSA_N  ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_string( &K, 16, RSA_P  ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_string( &K, 16, RSA_Q  ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_string( &K, 16, RSA_D  ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_mpi_read_string( &K, 16, RSA_E  ) );
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
+
+    MBEDCRYPTO_MPI_CHK( mbedcrypto_rsa_complete( &rsa ) );
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "  RSA key validation: " );
+
+    if( mbedcrypto_rsa_check_pubkey(  &rsa ) != 0 ||
+        mbedcrypto_rsa_check_privkey( &rsa ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "passed\n  PKCS#1 encryption : " );
+
+    memcpy( rsa_plaintext, RSA_PT, PT_LEN );
+
+    if( mbedcrypto_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDCRYPTO_RSA_PUBLIC,
+                                   PT_LEN, rsa_plaintext,
+                                   rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "passed\n  PKCS#1 decryption : " );
+
+    if( mbedcrypto_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDCRYPTO_RSA_PRIVATE,
+                                   &len, rsa_ciphertext, rsa_decrypted,
+                                   sizeof(rsa_decrypted) ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "passed\n" );
+
+#if defined(MBEDCRYPTO_SHA1_C)
+    if( verbose != 0 )
+        mbedcrypto_printf( "  PKCS#1 data sign  : " );
+
+    if( mbedcrypto_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( mbedcrypto_rsa_pkcs1_sign( &rsa, myrand, NULL,
+                                MBEDCRYPTO_RSA_PRIVATE, MBEDCRYPTO_MD_SHA1, 0,
+                                sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "passed\n  PKCS#1 sig. verify: " );
+
+    if( mbedcrypto_rsa_pkcs1_verify( &rsa, NULL, NULL,
+                                  MBEDCRYPTO_RSA_PUBLIC, MBEDCRYPTO_MD_SHA1, 0,
+                                  sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedcrypto_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "passed\n" );
+#endif /* MBEDCRYPTO_SHA1_C */
+
+    if( verbose != 0 )
+        mbedcrypto_printf( "\n" );
+
+cleanup:
+    mbedcrypto_mpi_free( &K );
+    mbedcrypto_rsa_free( &rsa );
+#else /* MBEDCRYPTO_PKCS1_V15 */
+    ((void) verbose);
+#endif /* MBEDCRYPTO_PKCS1_V15 */
+    return( ret );
+}
+
+#endif /* MBEDCRYPTO_SELF_TEST */
+
+#endif /* MBEDCRYPTO_RSA_C */
