Implement new RSA interface functions
diff --git a/library/rsa.c b/library/rsa.c
index 7a7f2f1..c807f91 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -459,18 +459,339 @@
     return( ret );
 }
 
+
+/*
+ * Default RSA interface implementation
+ */
+
+
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E )
+{
+    int ret;
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    if( N != NULL )
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+
+    return( 0 );
+}
+
+int mbedtls_rsa_import_raw( mbedtls_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;
+
+    if( N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    return( 0 );
+}
+
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx,
+                          int (*f_rng)(void *, unsigned char *, size_t),
+                          void *p_rng )
 {
     int ret = 0;
 
+    const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
+    const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
+    const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
+    const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
+    const int have_E = ( mbedtls_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 complete   = have_N &&  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;
 
+    const int is_priv = complete || pq_missing || d_missing;
 
+    if( !is_priv && !is_pub )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Step 1: Deduce and verify all core parameters.
+     */
+
+    if( pq_missing )
+    {
+        /* This includes sanity checking of core parameters,
+         * so no further checks necessary. */
+        ret = mbedtls_rsa_deduce_moduli( &ctx->N, &ctx->D, &ctx->E,
+                                         f_rng, p_rng,
+                                         &ctx->P, &ctx->Q );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    }
+    else if( d_missing )
+    {
+        /* If a PRNG is provided, check if P, Q are prime. */
+        if( f_rng != NULL  &&
+            ( ( ret = mbedtls_mpi_is_prime( &ctx->P, f_rng, p_rng ) ) != 0 ||
+              ( ret = mbedtls_mpi_is_prime( &ctx->Q, f_rng, p_rng ) ) != 0 ) )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        /* Compute N if missing. */
+        if( !have_N &&
+            ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        /* Deduce private exponent. This includes double-checking of the result,
+         * so together with the primality test above all core parameters are
+         * guaranteed to be sane if this call succeeds. */
+        if( ( ret = mbedtls_rsa_deduce_private( &ctx->P, &ctx->Q,
+                                                &ctx->D, &ctx->E ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+    }
+    else if( complete )
+    {
+        /* Check complete set of imported core parameters. */
+        if( ( ret = mbedtls_rsa_check_params( &ctx->N, &ctx->P, &ctx->Q,
+                                              &ctx->D, &ctx->E,
+                                              f_rng, p_rng ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+    }
+
+    /* In the remaining case of a public key, there's nothing to check for. */
+
+    /*
+     * Step 2: Deduce all additional parameters specific
+     *         to our current RSA implementaiton.
+     */
+
+    if( is_priv )
+    {
+        ret = mbedtls_rsa_deduce_crt( &ctx->P,  &ctx->Q,  &ctx->D,
+                                      &ctx->DP, &ctx->DQ, &ctx->QP );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    /*
+     * Step 3: Double check
+     */
+
+    if( is_priv )
+    {
+        if( ( ret = mbedtls_rsa_check_privkey( ctx ) ) != 0 )
+            return( ret );
+    }
+    else
+    {
+        if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
+            return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Check if CRT parameters match RSA context.
+ * This has to be implemented even if CRT is not used,
+ * in order to be able to validate DER encoded RSA keys,
+ * which always contain CRT parameters.
+ */
+int mbedtls_rsa_check_crt( mbedtls_rsa_context *ctx, mbedtls_mpi *DP,
+                           mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    /* Check if key is private or public */
+    const int opt_present =
+        mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0;
+
+    if( !opt_present )
+    {
+        /* Checking optional parameters only makes sense for private keys. */
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /* Alternative implementations not having DP, DQ, QP as part of
+     * the RSA context structure could perform the following checks instead:
+     * (1) Check that DP - P     == 0 mod P - 1
+     * (2) Check that DQ - Q     == 0 mod Q - 1
+     * (3) Check that QP * P - 1 == 0 mod P
+     */
+
+    if( ( DP != NULL && mbedtls_mpi_cmp_mpi( DP, &ctx->DP ) != 0 ) ||
+        ( DQ != NULL && mbedtls_mpi_cmp_mpi( DQ, &ctx->DQ ) != 0 ) ||
+        ( QP != NULL && mbedtls_mpi_cmp_mpi( QP, &ctx->QP ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_rsa_export_raw( const mbedtls_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 =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_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( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    if( N != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
 
 cleanup:
 
     return( ret );
 }
 
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+                        mbedtls_mpi *D, mbedtls_mpi *E )
+{
+    int ret;
+
+    /* Check if key is private or public */
+    int is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_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( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    /* Export all requested core parameters. */
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_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 mbedtls_rsa_deduce_crt
+ * can be used in this case.
+ */
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    int ret;
+
+    /* Check if key is private or public */
+    int is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /* Export all requested blinding parameters. */
+
+    if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
+        ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
+        ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
 
 /*
  * Initialize an RSA context
@@ -497,6 +818,16 @@
     ctx->hash_id = hash_id;
 }
 
+/*
+ * Get length in bytes of RSA modulus
+ */
+
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
+{
+    return( mbedtls_mpi_size( &ctx->N ) );
+}
+
+
 #if defined(MBEDTLS_GENPRIME)
 
 /*