Merged RIPEMD-160 support
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 257f6df..558aedf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,9 @@
 if(CMAKE_COMPILER_IS_GNUCC)
   add_subdirectory(tests)
 endif(CMAKE_COMPILER_IS_GNUCC)
+if(CMAKE_COMPILER_IS_CLANG)
+  add_subdirectory(tests)
+endif(CMAKE_COMPILER_IS_CLANG)
 
 add_subdirectory(programs)
 
diff --git a/ChangeLog b/ChangeLog
index 03215e7..0daed08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 PolarSSL ChangeLog (Sorted per branch, date)
 
+= PolarSSL 1.3 branch
+Features
+   * Support for the Koblitz curves: secp192k1, secp224k1, secp256k1
+   * Support for RIPEMD-160
+   * Allow for use of PKCS#1 v2.1 via the PK layer (pk_rsa_set_padding() and
+     rsa_set_padding())
+
+Bugfix
+   * Potential memory leak in bignum_selftest()
+   * Replaced expired test certificate
+
 = PolarSSL 1.3.3 released on 2013-12-31
 Features
    * EC key generation support in gen_key app
diff --git a/doxygen/input/doc_encdec.h b/doxygen/input/doc_encdec.h
index a78a869..7d37d93 100644
--- a/doxygen/input/doc_encdec.h
+++ b/doxygen/input/doc_encdec.h
@@ -34,6 +34,7 @@
  *     \c camellia_crypt_cfb128() and \c camellia_crypt_ctr()).
  *   - DES/3DES (see \c des_crypt_ecb(), \c des_crypt_cbc(), \c des3_crypt_ecb()
  *     and \c des3_crypt_cbc()).
+ *   - GCM (AES-GCM and CAMELLIA-GCM) (see \c gcm_init())
  *   - XTEA (see \c xtea_crypt_ecb()).
  * - Asymmetric:
  *   - Diffie-Hellman-Merkle (see \c dhm_read_public(), \c dhm_make_public()
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 89fd261..e261e7a 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -260,6 +260,9 @@
 #define POLARSSL_ECP_DP_SECP256R1_ENABLED
 #define POLARSSL_ECP_DP_SECP384R1_ENABLED
 #define POLARSSL_ECP_DP_SECP521R1_ENABLED
+#define POLARSSL_ECP_DP_SECP192K1_ENABLED
+#define POLARSSL_ECP_DP_SECP224K1_ENABLED
+#define POLARSSL_ECP_DP_SECP256K1_ENABLED
 #define POLARSSL_ECP_DP_BP256R1_ENABLED
 #define POLARSSL_ECP_DP_BP384R1_ENABLED
 #define POLARSSL_ECP_DP_BP512R1_ENABLED
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index 1e9e737..d98146c 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -68,6 +68,9 @@
     POLARSSL_ECP_DP_M255,           /*!< Curve25519               */
     POLARSSL_ECP_DP_M383,           /*!< (not implemented yet)    */
     POLARSSL_ECP_DP_M511,           /*!< (not implemented yet)    */
+    POLARSSL_ECP_DP_SECP192K1,      /*!< (not implemented yet)    */
+    POLARSSL_ECP_DP_SECP224K1,      /*!< (not implemented yet)    */
+    POLARSSL_ECP_DP_SECP256K1,      /*!< 256-bits Koblitz curve   */
 } ecp_group_id;
 
 /**
@@ -75,7 +78,7 @@
  *
  * (Montgomery curves excluded for now.)
  */
-#define POLARSSL_ECP_DP_MAX     9
+#define POLARSSL_ECP_DP_MAX     12
 
 /**
  * Curve information for use by other modules
diff --git a/include/polarssl/oid.h b/include/polarssl/oid.h
index 93ef8a6..f000b8e 100644
--- a/include/polarssl/oid.h
+++ b/include/polarssl/oid.h
@@ -263,7 +263,7 @@
 #define OID_EC_ALG_ECDH                 OID_CERTICOM "\x01\x0c"
 
 /*
- * ECParameters namedCurve identifiers, from RFC 5480 and RFC 5639
+ * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
  */
 
 /* secp192r1 OBJECT IDENTIFIER ::= {
@@ -286,6 +286,18 @@
  *   iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
 #define OID_EC_GRP_SECP521R1        OID_CERTICOM "\x00\x23"
 
+/* secp192k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
+#define OID_EC_GRP_SECP192K1        OID_CERTICOM "\x00\x1f"
+
+/* secp224k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
+#define OID_EC_GRP_SECP224K1        OID_CERTICOM "\x00\x20"
+
+/* secp256k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
+#define OID_EC_GRP_SECP256K1        OID_CERTICOM "\x00\x0a"
+
 /* RFC 5639 4.1
  * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
  * identified-organization(3) teletrust(36) algorithm(3) signature-
diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h
index 013d973..8b84471 100644
--- a/include/polarssl/pk.h
+++ b/include/polarssl/pk.h
@@ -222,11 +222,31 @@
  *                  POLARSSL_ERR_PK_BAD_INPUT_DATA on invalid input,
  *                  POLARSSL_ERR_PK_MALLOC_FAILED on allocation failure.
  *
- * \note            For contexts holding an RSA-alt key, use
+ * \note            For RSA contexts, padding defaults to PKCS_V15.
+ *                  Use pk_rsa_set_padding() to change it.
+ *
+ * \note            To create a context holding an RSA-alt key, use
  *                  \c pk_init_ctx_rsa_alt() instead.
  */
 int pk_init_ctx( pk_context *ctx, const pk_info_t *info );
 
+#if defined(POLARSSL_RSA_C)
+/**
+ * \brief          Set the padding method for an RSA key
+ *
+ *                 Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
+ *                 encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \param ctx      PK context to be set
+ * \param padding  RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id  RSA_PKCS_V21 hash identifier
+ *
+ * \note           The hash_id parameter is actually ignored
+ *                 when using RSA_PKCS_V15 padding.
+ */
+int pk_rsa_set_padding( pk_context *ctx, int padding, int hash_id );
+#endif /* POLARSSL_RSA_C */
+
 /**
  * \brief           Initialize an RSA-alt context
  *
diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h
index 504dde2..47315a3 100644
--- a/include/polarssl/rsa.h
+++ b/include/polarssl/rsa.h
@@ -125,7 +125,24 @@
  */
 void rsa_init( rsa_context *ctx,
                int padding,
-               int hash_id);
+               int hash_id );
+
+/**
+ * \brief          Set the padding method on an initilized RSA context.
+ *
+ *                 Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP
+ *                 encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \param ctx      RSA context to be set
+ * \param padding  RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id  RSA_PKCS_V21 hash identifier
+ *
+ * \note           The hash_id parameter is actually ignored
+ *                 when using RSA_PKCS_V15 padding.
+ */
+void rsa_set_padding( rsa_context *ctx,
+                      int padding,
+                      int hash_id );
 
 /**
  * \brief          Generate an RSA keypair
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 7e668f9..1bda2b3 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -972,17 +972,22 @@
 int ssl_set_session( ssl_context *ssl, const ssl_session *session );
 
 /**
- * \brief               Set the list of allowed ciphersuites
+ * \brief               Set the list of allowed ciphersuites and the preference
+ *                      order. First in the list has the highest preference.
  *                      (Overrides all version specific lists)
  *
+ *                      Note: The PolarSSL SSL server uses its own preferences
+ *                      over the preference of the connection SSL client unless
+ *                      POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined!
+ *
  * \param ssl           SSL context
  * \param ciphersuites  0-terminated list of allowed ciphersuites
  */
 void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites );
 
 /**
- * \brief               Set the list of allowed ciphersuites for a specific
- *                      version of the protocol.
+ * \brief               Set the list of allowed ciphersuites and the
+ *                      preference order for a specific version of the protocol.
  *                      (Only useful on the server side)
  *
  * \param ssl           SSL context
diff --git a/library/bignum.c b/library/bignum.c
index eb7a822..61b21fb 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1527,6 +1527,7 @@
      */
     mpi_montg_init( &mm, N );
     mpi_init( &RR ); mpi_init( &T );
+    mpi_init( &Apos );
     memset( W, 0, sizeof( W ) );
 
     i = mpi_msb( E );
@@ -1546,8 +1547,6 @@
      * Compensate for negative A (and correct at the end)
      */
     neg = ( A->s == -1 );
-
-    mpi_init( &Apos );
     if( neg )
     {
         MPI_CHK( mpi_copy( &Apos, A ) );
@@ -2196,7 +2195,8 @@
         if( verbose != 0 )
             printf( "failed\n" );
 
-        return( 1 );
+        ret = 1;
+        goto cleanup;
     }
 
     if( verbose != 0 )
@@ -2221,7 +2221,8 @@
         if( verbose != 0 )
             printf( "failed\n" );
 
-        return( 1 );
+        ret = 1;
+        goto cleanup;
     }
 
     if( verbose != 0 )
@@ -2242,7 +2243,8 @@
         if( verbose != 0 )
             printf( "failed\n" );
 
-        return( 1 );
+        ret = 1;
+        goto cleanup;
     }
 
     if( verbose != 0 )
@@ -2263,7 +2265,8 @@
         if( verbose != 0 )
             printf( "failed\n" );
 
-        return( 1 );
+        ret = 1;
+        goto cleanup;
     }
 
     if( verbose != 0 )
@@ -2277,15 +2280,16 @@
         MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
         MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
 
-	    MPI_CHK( mpi_gcd( &A, &X, &Y ) );
+        MPI_CHK( mpi_gcd( &A, &X, &Y ) );
 
-	    if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
-	    {
-		    if( verbose != 0 )
-			    printf( "failed at %d\n", i );
+        if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+        {
+            if( verbose != 0 )
+                printf( "failed at %d\n", i );
 
-		    return( 1 );
-	    }
+            ret = 1;
+            goto cleanup;
+        }
     }
 
     if( verbose != 0 )
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 53b8b54..c2f78a4 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -105,7 +105,7 @@
     unsigned char tmp[CTR_DRBG_SEEDLEN];
     unsigned char key[CTR_DRBG_KEYSIZE];
     unsigned char chain[CTR_DRBG_BLOCKSIZE];
-    unsigned char *p = buf, *iv;
+    unsigned char *p, *iv;
     aes_context aes_ctx;
 
     int i, j;
diff --git a/library/ecdh.c b/library/ecdh.c
index 302531d..cd65690 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -246,7 +246,7 @@
     if( mpi_size( &ctx->z ) > blen )
         return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
 
-    *olen = ctx->grp.nbits / 8 + ( ( ctx->grp.nbits % 8 ) != 0 );
+    *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
     return mpi_write_binary( &ctx->z, buf, *olen );
 }
 
@@ -258,7 +258,8 @@
  */
 int ecdh_self_test( int verbose )
 {
-    return( verbose++ );
+    ((void) verbose );
+    return( 0 );
 }
 
 #endif
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 2072d55..ced402a 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -43,8 +43,16 @@
 static int derive_mpi( const ecp_group *grp, mpi *x,
                        const unsigned char *buf, size_t blen )
 {
+    int ret;
     size_t n_size = (grp->nbits + 7) / 8;
-    return( mpi_read_binary( x, buf, blen > n_size ? n_size : blen ) );
+    size_t use_size = blen > n_size ? n_size : blen;
+
+    MPI_CHK( mpi_read_binary( x, buf, use_size ) );
+    if( use_size * 8 > grp->nbits )
+        MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) );
+
+cleanup:
+    return( ret );
 }
 
 /*
@@ -349,7 +357,8 @@
  */
 int ecdsa_self_test( int verbose )
 {
-    return( verbose++ );
+    ((void) verbose );
+    return( 0 );
 }
 
 #endif
diff --git a/library/ecp.c b/library/ecp.c
index 8b34bf3..0bef955 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -141,6 +141,15 @@
 #if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
     { POLARSSL_ECP_DP_SECP192R1,    19,     192,    "secp192r1"         },
 #endif
+#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+    { POLARSSL_ECP_DP_SECP256K1,    22,     256,    "secp256k1"         },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED)
+    { POLARSSL_ECP_DP_SECP224K1,    20,     224,    "secp224k1"         },
+#endif
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED)
+    { POLARSSL_ECP_DP_SECP192K1,    18,     192,    "secp192k1"         },
+#endif
     { POLARSSL_ECP_DP_NONE,          0,     0,      NULL                },
 };
 
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 706e0ee..db158fe 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -318,6 +318,101 @@
 };
 #endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
 
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED)
+static t_uint secp192k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp192k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static t_uint secp192k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x03, 0x00 ),
+};
+static t_uint secp192k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
+    BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
+    BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
+};
+static t_uint secp192k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
+    BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
+};
+static t_uint secp192k1_n[] = {
+    BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED)
+static t_uint secp224k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp224k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static t_uint secp224k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x05, 0x00 ),
+};
+static t_uint secp224k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
+    BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
+    BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
+    BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
+};
+static t_uint secp224k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
+    BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
+    BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
+    BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
+};
+static t_uint secp224k1_n[] = {
+    BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
+    BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
+};
+#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+static t_uint secp256k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static t_uint secp256k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static t_uint secp256k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x07, 0x00 ),
+};
+static t_uint secp256k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
+    BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
+    BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
+    BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
+};
+static t_uint secp256k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
+    BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
+    BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
+    BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
+};
+static t_uint secp256k1_n[] = {
+    BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
+    BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */
+
 /*
  * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
  */
@@ -548,15 +643,26 @@
 #if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
 static int ecp_mod_p521( mpi * );
 #endif
-#if defined(POLARSSL_ECP_DP_M255_ENABLED)
-static int ecp_mod_p255( mpi * );
-#endif
 
 #define NIST_MODP( P )      grp->modp = ecp_mod_ ## P;
 #else
 #define NIST_MODP( P )
 #endif /* POLARSSL_ECP_NIST_OPTIM */
 
+/* Additional forward declarations */
+#if defined(POLARSSL_ECP_DP_M255_ENABLED)
+static int ecp_mod_p255( mpi * );
+#endif
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED)
+static int ecp_mod_p192k1( mpi * );
+#endif
+#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED)
+static int ecp_mod_p224k1( mpi * );
+#endif
+#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+static int ecp_mod_p256k1( mpi * );
+#endif
+
 #define LOAD_GROUP_A( G )   ecp_group_load( grp,            \
                             G ## _p,  sizeof( G ## _p  ),   \
                             G ## _a,  sizeof( G ## _a  ),   \
@@ -648,6 +754,24 @@
             return( LOAD_GROUP( secp521r1 ) );
 #endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */
 
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED)
+        case POLARSSL_ECP_DP_SECP192K1:
+            grp->modp = ecp_mod_p192k1;
+            return( LOAD_GROUP_A( secp192k1 ) );
+#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED)
+        case POLARSSL_ECP_DP_SECP224K1:
+            grp->modp = ecp_mod_p224k1;
+            return( LOAD_GROUP_A( secp224k1 ) );
+#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+        case POLARSSL_ECP_DP_SECP256K1:
+            grp->modp = ecp_mod_p256k1;
+            return( LOAD_GROUP_A( secp256k1 ) );
+#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */
+
 #if defined(POLARSSL_ECP_DP_BP256R1_ENABLED)
         case POLARSSL_ECP_DP_BP256R1:
             return( LOAD_GROUP_A( brainpoolP256r1 ) );
@@ -1085,7 +1209,7 @@
 
 /*
  * Fast quasi-reduction modulo p255 = 2^255 - 19
- * Write N as A1 + 2^255 A1, return A0 + 19 * A1
+ * Write N as A0 + 2^255 A1, return A0 + 19 * A1
  */
 static int ecp_mod_p255( mpi *N )
 {
@@ -1122,4 +1246,131 @@
 }
 #endif /* POLARSSL_ECP_DP_M255_ENABLED */
 
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) ||   \
+    defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) ||   \
+    defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo P = 2^s - R,
+ * with R about 33 bits, used by the Koblitz curves.
+ *
+ * Write N as A0 + 2^224 A1, return A0 + R * A1.
+ * Actually do two passes, since R is big.
+ */
+#define P_KOBLITZ_MAX   ( 256 / 8 / sizeof( t_uint ) )  // Max limbs in P
+#define P_KOBLITZ_R     ( 8 / sizeof( t_uint ) )        // Limbs in R
+static inline int ecp_mod_koblitz( mpi *N, t_uint *Rp, size_t p_limbs,
+                                   size_t adjust, size_t shift, t_uint mask )
+{
+    int ret;
+    size_t i;
+    mpi M, R;
+    t_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R];
+
+    if( N->n < p_limbs )
+        return( 0 );
+
+    /* Init R */
+    R.s = 1;
+    R.p = Rp;
+    R.n = P_KOBLITZ_R;
+
+    /* Common setup for M */
+    M.s = 1;
+    M.p = Mp;
+
+    /* M = A1 */
+    M.n = N->n - ( p_limbs - adjust );
+    if( M.n > p_limbs + adjust )
+        M.n = p_limbs + adjust;
+    memset( Mp, 0, sizeof Mp );
+    memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) );
+    if (shift != 0 )
+        MPI_CHK( mpi_shift_r( &M, shift ) );
+    M.n += R.n - adjust; /* Make room for multiplication by R */
+
+    /* N = A0 */
+    if (mask != 0 )
+        N->p[p_limbs - 1] &= mask;
+    for( i = p_limbs; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + R * A1 */
+    MPI_CHK( mpi_mul_mpi( &M, &M, &R ) );
+    MPI_CHK( mpi_add_abs( N, N, &M ) );
+
+    /* Second pass */
+
+    /* M = A1 */
+    M.n = N->n - ( p_limbs - adjust );
+    if( M.n > p_limbs + adjust )
+        M.n = p_limbs + adjust;
+    memset( Mp, 0, sizeof Mp );
+    memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) );
+    if (shift != 0 )
+        MPI_CHK( mpi_shift_r( &M, shift ) );
+    M.n += R.n - adjust; /* Make room for multiplication by R */
+
+    /* N = A0 */
+    if (mask != 0 )
+        N->p[p_limbs - 1] &= mask;
+    for( i = p_limbs; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + R * A1 */
+    MPI_CHK( mpi_mul_mpi( &M, &M, &R ) );
+    MPI_CHK( mpi_add_abs( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED) ||
+          POLARSSL_ECP_DP_SECP224K1_ENABLED) ||
+          POLARSSL_ECP_DP_SECP256K1_ENABLED) */
+
+#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p192k1 = 2^192 - R,
+ * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
+ */
+static int ecp_mod_p192k1( mpi *N )
+{
+    static t_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+
+    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( t_uint ), 0, 0, 0 ) );
+}
+#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p224k1 = 2^224 - R,
+ * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
+ */
+static int ecp_mod_p224k1( mpi *N )
+{
+    static t_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+
+#if defined(POLARSSL_HAVE_INT64)
+    return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
+#else
+    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( t_uint ), 0, 0, 0 ) );
+#endif
+}
+
+#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p256k1 = 2^256 - R,
+ * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
+ */
+static int ecp_mod_p256k1( mpi *N )
+{
+    static t_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( t_uint ), 0, 0, 0 ) );
+}
+#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */
+
 #endif
diff --git a/library/gcm.c b/library/gcm.c
index 8950360..3e1bc77 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -439,11 +439,17 @@
                       const unsigned char *input,
                       unsigned char *output )
 {
+    int ret;
     unsigned char check_tag[16];
     size_t i;
     int diff;
 
-    gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
+    if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length,
+                                   iv, iv_len, add, add_len,
+                                   input, output, tag_len, check_tag ) ) != 0 )
+    {
+        return( ret );
+    }
 
     /* Check tag in "constant-time" */
     for( diff = 0, i = 0; i < tag_len; i++ )
diff --git a/library/oid.c b/library/oid.c
index b0b551d..f943c6d 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -403,6 +403,18 @@
         POLARSSL_ECP_DP_SECP521R1,
     },
     {
+        { ADD_LEN( OID_EC_GRP_SECP192K1 ), "secp192k1",    "secp192k1" },
+        POLARSSL_ECP_DP_SECP192K1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP224K1 ), "secp224k1",    "secp224k1" },
+        POLARSSL_ECP_DP_SECP224K1,
+    },
+    {
+        { ADD_LEN( OID_EC_GRP_SECP256K1 ), "secp256k1",    "secp256k1" },
+        POLARSSL_ECP_DP_SECP256K1,
+    },
+    {
         { ADD_LEN( OID_EC_GRP_BP256R1 ),   "brainpoolP256r1","brainpool256r1" },
         POLARSSL_ECP_DP_BP256R1,
     },
diff --git a/library/pk.c b/library/pk.c
index 80eccc9..d1bd215 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -109,6 +109,20 @@
 }
 
 /*
+ * Set RSA padding
+ */
+int pk_rsa_set_padding( pk_context *ctx, int padding, int hash_id )
+{
+    if( ctx == NULL || ctx->pk_info == NULL ||
+        ctx->pk_info->type != POLARSSL_PK_RSA )
+        return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
+
+    rsa_set_padding( pk_rsa( *ctx ), padding, hash_id );
+
+    return( 0 );
+}
+
+/*
  * Initialize an RSA-alt context
  */
 int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
diff --git a/library/rsa.c b/library/rsa.c
index af07a49..75cae7e 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -60,6 +60,17 @@
 #endif
 }
 
+/*
+ * Set padding method after initialisation
+ */
+void rsa_set_padding( rsa_context *ctx,
+                      int padding,
+                      int hash_id)
+{
+    ctx->padding = padding;
+    ctx->hash_id = hash_id;
+}
+
 #if defined(POLARSSL_GENPRIME)
 
 /*
@@ -911,8 +922,6 @@
 
     memset( sig, 0, olen );
 
-    msb = mpi_msb( &ctx->N ) - 1;
-
     // Generate salt of length slen
     //
     if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index c07de49..e91546b 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -1650,6 +1650,7 @@
 }
 #endif
 
+#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
 int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info )
 {
     switch( info->key_exchange )
@@ -1665,7 +1666,9 @@
             return( 0 );
     }
 }
+#endif
 
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 int ssl_ciphersuite_uses_psk( const ssl_ciphersuite_t *info )
 {
     switch( info->key_exchange )
@@ -1680,5 +1683,6 @@
             return( 0 );
     }
 }
+#endif
 
 #endif
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index e738028..36378ef 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -596,6 +596,12 @@
 #if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
+        if( transform->maclen > sizeof transform->mac_enc )
+        {
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
+
         memcpy( transform->mac_enc, mac_enc, transform->maclen );
         memcpy( transform->mac_dec, mac_dec, transform->maclen );
     }
@@ -1091,8 +1097,6 @@
         unsigned char add_data[13];
         int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
 
-        enc_msglen = ssl->out_msglen;
-
         memcpy( add_data, ssl->out_ctr, 8 );
         add_data[8]  = ssl->out_msgtype;
         add_data[9]  = ssl->major_ver;
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 8632f71..27d5ec0 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -543,8 +543,6 @@
 
     memcpy( p, buf, buflen );
 
-    buflen = 0;
-
     crt->raw.p = p;
     crt->raw.len = len;
     end = p + len;
diff --git a/library/x509_csr.c b/library/x509_csr.c
index c0c7679..e45935a 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -112,13 +112,7 @@
     if( ret == 0 )
     {
         /*
-         * Was PEM encoded
-         */
-        buflen -= use_len;
-        buf += use_len;
-
-        /*
-         * Steal PEM buffer
+         * Was PEM encoded, steal PEM buffer
          */
         p = pem.buf;
         pem.buf = NULL;
@@ -142,8 +136,6 @@
             return( POLARSSL_ERR_X509_MALLOC_FAILED );
 
         memcpy( p, buf, buflen );
-
-        buflen = 0;
     }
 
     csr->raw.p = p;
diff --git a/programs/.gitignore b/programs/.gitignore
index 50f1521..a47ef06 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -32,6 +32,7 @@
 ssl/ssl_client2
 ssl/ssl_fork_server
 ssl/ssl_mail_client
+ssl/ssl_pthread_server
 ssl/ssl_server
 ssl/ssl_server2
 test/benchmark
diff --git a/tests/data_files/cert_example_multi_nocn.crt b/tests/data_files/cert_example_multi_nocn.crt
index 12ea661..1634846 100644
--- a/tests/data_files/cert_example_multi_nocn.crt
+++ b/tests/data_files/cert_example_multi_nocn.crt
@@ -1,33 +1,13 @@
 -----BEGIN CERTIFICATE-----
-MIIFiTCCA3GgAwIBAgIDC0EHMA0GCSqGSIb3DQEBBQUAMHkxEDAOBgNVBAoTB1Jv
-b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ
-Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y
-dEBjYWNlcnQub3JnMB4XDTEyMDEyMjEzMzEzNFoXDTE0MDEyMTEzMzEzNFowADCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdnVW27pPxX6JD8XER1w2P/
-8E8g44KtOtgIFIMnaoUAwNOePDvo8HfGo06AVCRntCPfGHJu5t5EmuudQjvC7gcL
-Of1/LIFXFhe59f8yH5peGV8rPKyyNNV3YCIAn1WmuaP9a/Yk7YEvYOBntFVTIFvN
-s0x7jmyCz7A51WApun91Z6Qz2muiUDb9mmfX/INR63p1TDG9PeGzUIaZFFZt8BYH
-NTyu95cxpUOTBCFi4pOj/WBuF2MPUv7RRYOHfBOnAS3h7+8eOX/oNu9YUhneVbuE
-Zqs47lbITTi6tmpYnZQ8gQdJQrfDLI/taw6oIRXhH1U/P1NYlGcz8/BbC33FOA0C
-AwEAAaOCAZEwggGNMAwGA1UdEwEB/wQCMAAwNAYDVR0lBC0wKwYIKwYBBQUHAwIG
-CCsGAQUFBwMBBglghkgBhvhCBAEGCisGAQQBgjcKAwMwCwYDVR0PBAQDAgWgMDMG
-CCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuY2FjZXJ0Lm9y
-Zy8wggEDBgNVHREEgfswgfiCHHd3dy5zaG90b2thbi1icmF1bnNjaHdlaWcuZGWg
-KgYIKwYBBQUHCAWgHgwcd3d3LnNob3Rva2FuLWJyYXVuc2Nod2VpZy5kZYIUd3d3
-Lm1hc3NpbW8tYWJhdGUuZXWgIgYIKwYBBQUHCAWgFgwUd3d3Lm1hc3NpbW8tYWJh
-dGUuZXWCFHd3dy5tYXNzaW1vLWFiYXRlLmRloCIGCCsGAQUFBwgFoBYMFHd3dy5t
-YXNzaW1vLWFiYXRlLmRlghR3d3cubWFzc2ltby1hYmF0ZS5pdKAiBggrBgEFBQcI
-BaAWDBR3d3cubWFzc2ltby1hYmF0ZS5pdDANBgkqhkiG9w0BAQUFAAOCAgEAT8uP
-gDouHoXj4iMF0iqJTGp27zyaBajKZ3Lkxjks/YsH/vJfqLTFtVqr5EWTQHbOelZf
-Ijpagiv2Qz/wfKSK9Bi9oEiB1WiTxtfI5nX5bWtWcLk44OaxMFpEQUflgvbqQqLV
-+YCUgXf2fKDtGmXF6edE6luEN0UGC29lYW5DF7KHRkM3Eu/7KZG9PfJO5evhb7Os
-LMsEWl3ESJjFDzgkfrWFqKOXO2sRfzRaagPgeZMVxFMDgtvarRU0aumOTftcX1yD
-ayc5a71i03cbo7p1UhfcivQ30d3wfhVOdmsr99agPLolqKQaxGs5INf7T9v98Obf
-1Ax8jrT5VcH/74MCReBbE6wwr8CiSrHVyzFLK828jeStw9vNqlUh/Ny6pf4au2C3
-vmFTlEd0riCvvRQYRa/qQSwLD36rfFd8grdvD4Brw0gJkRjmkEy37bM35op0mZFu
-6eaWURasEUgG6IFBtAGRvZFxSHCbM6o6KMNbTsaCYMfHszCJwzSSCYo1n1qqgE2r
-JITT2l/XA/KBwKnH+XpKPe4ffpfkCFUdm2phxe41HBLcbLdPjvvrDfU1IcdSAVVR
-4swr+Kd3S044WL660s1h4xpFkWc0KG9ghe4vOUlmwqV7mO8EhLyu4ustyep2Jv2e
-91oCC+CDllr3qfAUQOUcqlSPWogMZ9tTDx58ids=
+MIIB/TCCAWagAwIBAgIJAPfGf/jpqWP5MA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV
+BAYTAk5MMB4XDTE0MDEyMjEwMDQzM1oXDTI0MDEyMjEwMDQzM1owDTELMAkGA1UE
+BhMCTkwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN0Rip+ZurBoyirqO2pt
+WZftTslU5A3uzqB9oB6q6A7CuxNA24oSjokTJKXF9frY9ZDXyMrLxf6THa/aEiNz
+UnlGGrqgVyt2FjGzqK/nOJsIi2OZOgol7kXSGFi6uZMa7dRYmmMbN/z3FAifhWVJ
+81kybdHg6G3eUu1mtKkL2kCVAgMBAAGjZTBjMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgXgMEkGA1UdEQRCMECCHHd3dy5zaG90b2thbi1icmF1bnNjaHdlaWcuZGWCFHd3
+dy5tYXNzaW1vLWFiYXRlLmV1hwTAqAEBhwTAqEWQMA0GCSqGSIb3DQEBBQUAA4GB
+ABjx1ytrqCyFC5/0cjWnbLK9vsvLny2ZikDewfRxqJ5zAxGWLqHOr1SmUmu2DrvB
+bkT9g5z19+iMhPnzJz1x7Q2m7WTIJTuUPK+hKZJATDLNhZ86h5Nkw8k9YzKcOrPm
+EIqsy55CSgLU0ntljqSBvSb4ifrF1NnIWej2lSfN6r+3
 -----END CERTIFICATE-----
-
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 8cce3e6..444e207 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -423,5 +423,17 @@
 depends_on:POLARSSL_ECP_DP_M255_ENABLED
 ecp_test_vec_x:POLARSSL_ECP_DP_M255:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"057E23EA9F1CBE8A27168F6E696A791DE61DD3AF7ACD4EEACC6E7BA514FDA863":"47DC3D214174820E1154B49BC6CDB2ABD45EE95817055D255AA35831B70D3260":"6EB89DA91989AE37C7EAC7618D9E5C4951DBA1D73C285AE1CD26A855020EEF04":"61450CD98E36016B58776A897A9F0AEF738B99F09468B8D6B8511184D53494AB"
 
+ECP test vectors secp192k1
+depends_on:POLARSSL_ECP_DP_SECP192K1_ENABLED
+ecp_test_vect:POLARSSL_ECP_DP_SECP192K1:"D1E13A359F6E0F0698791938E6D60246030AE4B0D8D4E9DE":"281BCA982F187ED30AD5E088461EBE0A5FADBB682546DF79":"3F68A8E9441FB93A4DD48CB70B504FCC9AA01902EF5BE0F3":"BE97C5D2A1A94D081E3FACE53E65A27108B7467BDF58DE43":"5EB35E922CD693F7947124F5920022C4891C04F6A8B8DCB2":"60ECF73D0FC43E0C42E8E155FFE39F9F0B531F87B34B6C3C":"372F5C5D0E18313C82AEF940EC3AFEE26087A46F1EBAE923":"D5A9F9182EC09CEAEA5F57EA10225EC77FA44174511985FD"
+
+ECP test vectors secp224k1
+depends_on:POLARSSL_ECP_DP_SECP224K1_ENABLED
+ecp_test_vect:POLARSSL_ECP_DP_SECP224K1:"8EAD9B2819A3C2746B3EDC1E0D30F23271CDAC048C0615C961B1A9D3":"DEE0A75EF26CF8F501DB80807A3A0908E5CF01852709C1D35B31428B":"276D2B817918F7CD1DA5CCA081EC4B62CD255E0ACDC9F85FA8C52CAC":"AB7E70AEDA68A174ECC1F3800561B2D4FABE97C5D2A1A94D081E3FAC":"D2E94B00FD30201C40EDF73B137427916687AEA1935B277A5960DD1C":"DE728A614B17D91EB3CB2C17DA195562B6281585986332B3E12DA0ED":"B66B673D29038A3487A2D9C10CDCE67646F7C39C984EBE9E8795AD3C":"928C6147AF5EE4B54FA6ECF77B70CA3FEE5F4182DB057878F129DF":
+
+ECP test vectors secp256k1
+depends_on:POLARSSL_ECP_DP_SECP256K1_ENABLED
+ecp_test_vect:POLARSSL_ECP_DP_SECP256K1:"923C6D4756CD940CD1E13A359F6E0F0698791938E6D60246030AE4B0D8D4E9DE":"20A865B295E93C5B090F324B84D7AC7526AA1CFE86DD80E792CECCD16B657D55":"38AC87141A4854A8DFD87333E107B61692323721FE2EAD6E52206FE471A4771B":"4F5036A8ED5809AB7E70AEDA68A174ECC1F3800561B2D4FABE97C5D2A1A94D08":"029F5D2CC5A2C7E538FBA321439B4EC8DD79B7FEB9C0A8A5114EEA39856E22E8":"165171AFC3411A427F24FDDE1192A551C90983EB421BC982AB4CF4E21F18F04B":"E4B5B537D3ACEA7624F2E9C185BFFD80BC7035E515F33E0D4CFAE747FD20038E":"2BC685B7DCDBC694F5E036C4EAE9BFB489D7BF8940C4681F734B71D68501514C"
+
 ECP selftest
 ecp_selftest:
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index e07495a..e7a52af 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -14,13 +14,21 @@
 depends_on:POLARSSL_ECDSA_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
 pk_utils:POLARSSL_PK_ECDSA:192:24:"ECDSA"
 
-RSA verify test vector #1 (good)
-depends_on:POLARSSL_SHA1_C:POLARSSL_PKCS1_V15
-pk_rsa_verify_test_vec:"206ef4bf396c6087f8229ef196fd35f37ccb8de5efcdb238f20d556668f114257a11fbe038464a67830378e62ae9791453953dac1dbd7921837ba98e84e856eb80ed9487e656d0b20c28c8ba5e35db1abbed83ed1c7720a97701f709e3547a4bfcabca9c89c57ad15c3996577a0ae36d7c7b699035242f37954646c1cd5c08ac":POLARSSL_MD_SHA1:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"5abc01f5de25b70867ff0c24e222c61f53c88daf42586fddcd56f3c4588f074be3c328056c063388688b6385a8167957c6e5355a510e005b8a851d69c96b36ec6036644078210e5d7d326f96365ee0648882921492bc7b753eb9c26cdbab37555f210df2ca6fec1b25b463d38b81c0dcea202022b04af5da58aa03d77be949b7":0
+PK RSA padding: RSA (ok)
+depends_on:POLARSSL_RSA_C
+pk_set_rsa_padding:POLARSSL_PK_RSA:RSA_PKCS_V21:POLARSSL_MD_SHA512:0
 
-RSA verify test vector #2 (bad)
+PK RSA padding: ECKEY (error)
+depends_on:POLARSSL_ECP_C
+pk_set_rsa_padding:POLARSSL_PK_ECKEY:RSA_PKCS_V21:POLARSSL_MD_SHA512:POLARSSL_ERR_PK_BAD_INPUT_DATA
+
+RSA verify test vector #1 (v1.5, good)
 depends_on:POLARSSL_SHA1_C:POLARSSL_PKCS1_V15
-pk_rsa_verify_test_vec:"d6248c3e96b1a7e5fea978870fcc4c9786b4e5156e16b7faef4557d667f730b8bc4c784ef00c624df5309513c3a5de8ca94c2152e0459618666d3148092562ebc256ffca45b27fd2d63c68bd5e0a0aefbe496e9e63838a361b1db6fc272464f191490bf9c029643c49d2d9cd08833b8a70b4b3431f56fb1eb55ccd39e77a9c92":POLARSSL_MD_SHA1:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"3203b7647fb7e345aa457681e5131777f1adc371f2fba8534928c4e52ef6206a856425d6269352ecbf64db2f6ad82397768cafdd8cd272e512d617ad67992226da6bc291c31404c17fd4b7e2beb20eff284a44f4d7af47fd6629e2c95809fa7f2241a04f70ac70d3271bb13258af1ed5c5988c95df7fa26603515791075feccd":POLARSSL_ERR_RSA_VERIFY_FAILED
+pk_rsa_verify_test_vec:"206ef4bf396c6087f8229ef196fd35f37ccb8de5efcdb238f20d556668f114257a11fbe038464a67830378e62ae9791453953dac1dbd7921837ba98e84e856eb80ed9487e656d0b20c28c8ba5e35db1abbed83ed1c7720a97701f709e3547a4bfcabca9c89c57ad15c3996577a0ae36d7c7b699035242f37954646c1cd5c08ac":POLARSSL_MD_SHA1:RSA_PKCS_V15:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"5abc01f5de25b70867ff0c24e222c61f53c88daf42586fddcd56f3c4588f074be3c328056c063388688b6385a8167957c6e5355a510e005b8a851d69c96b36ec6036644078210e5d7d326f96365ee0648882921492bc7b753eb9c26cdbab37555f210df2ca6fec1b25b463d38b81c0dcea202022b04af5da58aa03d77be949b7":0
+
+RSA verify test vector #2 (v1.5 bad)
+depends_on:POLARSSL_SHA1_C:POLARSSL_PKCS1_V15
+pk_rsa_verify_test_vec:"d6248c3e96b1a7e5fea978870fcc4c9786b4e5156e16b7faef4557d667f730b8bc4c784ef00c624df5309513c3a5de8ca94c2152e0459618666d3148092562ebc256ffca45b27fd2d63c68bd5e0a0aefbe496e9e63838a361b1db6fc272464f191490bf9c029643c49d2d9cd08833b8a70b4b3431f56fb1eb55ccd39e77a9c92":POLARSSL_MD_SHA1:RSA_PKCS_V15:1024:16:"e28a13548525e5f36dccb24ecb7cc332cc689dfd64012604c9c7816d72a16c3f5fcdc0e86e7c03280b1c69b586ce0cd8aec722cc73a5d3b730310bf7dfebdc77ce5d94bbc369dc18a2f7b07bd505ab0f82224aef09fdc1e5063234255e0b3c40a52e9e8ae60898eb88a766bdd788fe9493d8fd86bcdd2884d5c06216c65469e5":16:"3":"3203b7647fb7e345aa457681e5131777f1adc371f2fba8534928c4e52ef6206a856425d6269352ecbf64db2f6ad82397768cafdd8cd272e512d617ad67992226da6bc291c31404c17fd4b7e2beb20eff284a44f4d7af47fd6629e2c95809fa7f2241a04f70ac70d3271bb13258af1ed5c5988c95df7fa26603515791075feccd":POLARSSL_ERR_RSA_VERIFY_FAILED
 
 ECDSA verify test vector #1 (good)
 depends_on:POLARSSL_ECP_DP_SECP192R1_ENABLED
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 85cdb74..55a8663 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -54,15 +54,33 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void pk_set_rsa_padding( int type, int padding, int hash_id, int ret )
+{
+    pk_context pk;
+    unsigned char hash[50], sig[5000];
+    size_t sig_len;
+
+    pk_init( &pk );
+
+    memset( hash, 0x2a, sizeof hash );
+    memset( sig, 0, sizeof sig );
+
+    TEST_ASSERT( pk_init_ctx( &pk, pk_info_from_type( type ) ) == 0 );
+    TEST_ASSERT( pk_rsa_set_padding( &pk, padding, hash_id ) == ret );
+
+    pk_free( &pk );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_RSA_C */
-void pk_rsa_verify_test_vec( char *message_hex_string, int digest,
+void pk_rsa_verify_test_vec( char *message_hex_string, int digest, int scheme,
                        int mod, int radix_N, char *input_N, int radix_E,
                        char *input_E, char *result_hex_str, int result )
 {
     unsigned char message_str[1000];
     unsigned char hash_result[1000];
     unsigned char result_str[1000];
-    rsa_context *rsa;
     pk_context pk;
     int msg_len;
 
@@ -73,11 +91,16 @@
     memset( result_str, 0x00, 1000 );
 
     TEST_ASSERT( pk_init_ctx( &pk, pk_info_from_type( POLARSSL_PK_RSA ) ) == 0 );
-    rsa = pk_rsa( pk );
+    TEST_ASSERT( pk_rsa_set_padding( &pk, scheme, digest ) == 0 );
 
-    rsa->len = mod / 8;
-    TEST_ASSERT( mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
-    TEST_ASSERT( mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    /* Set RSA key manually */
+    {
+        rsa_context *rsa = pk_rsa( pk );
+
+        rsa->len = mod / 8;
+        TEST_ASSERT( mpi_read_string( &rsa->N, radix_N, input_N ) == 0 );
+        TEST_ASSERT( mpi_read_string( &rsa->E, radix_E, input_E ) == 0 );
+    }
 
     msg_len = unhexify( message_str, message_hex_string );
     unhexify( result_str, result_hex_str );