New function mbedtls_rsa_get_bitlen

Add a new function mbedtls_rsa_get_bitlen which returns the RSA key
size, i.e. the bit size of the modulus. In the pk module, call
mbedtls_rsa_get_bitlen instead of mbedtls_rsa_get_len, which gave the
wrong result for key sizes that are not a multiple of 8.

This commit adds one non-regression test in the pk suite. More tests
are needed for RSA key sizes that are a multiple of 8.

This commit does not address RSA alternative implementations, which
only provide an interface that return the modulus size in bytes.
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 6eea5af..31a8db7 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -404,6 +404,16 @@
 size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx );
 
 /**
+ * \brief          This function retrieves the length of the RSA modulus in bits.
+ *
+ * \param ctx      The initialized RSA context.
+ *
+ * \return         The length of the RSA modulus in bits.
+ *
+ */
+size_t mbedtls_rsa_get_bitlen( const mbedtls_rsa_context *ctx );
+
+/**
  * \brief          This function generates an RSA keypair.
  *
  * \note           mbedtls_rsa_init() must be called before this function,
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 2c7d2d7..f9b4c65 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -66,7 +66,7 @@
 static size_t rsa_get_bitlen( const void *ctx )
 {
     const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
-    return( 8 * mbedtls_rsa_get_len( rsa ) );
+    return( mbedtls_rsa_get_bitlen( rsa ) );
 }
 
 static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
diff --git a/library/rsa.c b/library/rsa.c
index 88c1cf1..ad19639 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -480,12 +480,19 @@
 /*
  * Get length in bytes of RSA modulus
  */
-
 size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
 {
     return( ctx->len );
 }
 
+/*
+ * Get length in bits of RSA modulus
+ */
+size_t mbedtls_rsa_get_bitlen( const mbedtls_rsa_context *ctx )
+{
+    return( mbedtls_mpi_bitlen( &ctx->N ) );
+}
+
 
 #if defined(MBEDTLS_GENPRIME)
 
diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data
index a066bd9..77e3bd8 100644
--- a/tests/suites/test_suite_pk.data
+++ b/tests/suites/test_suite_pk.data
@@ -1,7 +1,16 @@
-PK utils: RSA
+PK utils: RSA, 512 bits
 depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
 pk_utils:MBEDTLS_PK_RSA:512:64:"RSA"
 
+## RSA key generation only supports even bit sizes
+#PK utils: RSA, 511 bits
+#depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+#pk_utils:MBEDTLS_PK_RSA:511:64:"RSA"
+#
+PK utils: RSA, 510 bits
+depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME
+pk_utils:MBEDTLS_PK_RSA:510:64:"RSA"
+
 PK utils: ECKEY
 depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
 pk_utils:MBEDTLS_PK_ECKEY:192:24:"EC"
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 9005ddb..a1d9b0b 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -13,13 +13,18 @@
 #define RSA_KEY_SIZE 512
 #define RSA_KEY_LEN   64
 
-static int pk_genkey( mbedtls_pk_context *pk )
+static int pk_genkey( mbedtls_pk_context *pk, int size )
 {
     ((void) pk);
 
 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
     if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_RSA )
-        return mbedtls_rsa_gen_key( mbedtls_pk_rsa( *pk ), rnd_std_rand, NULL, RSA_KEY_SIZE, 3 );
+    {
+        if( size == 0 )
+            size = RSA_KEY_SIZE;
+        return( mbedtls_rsa_gen_key( mbedtls_pk_rsa( *pk ),
+                                     rnd_std_rand, NULL, size, 3 ) );
+    }
 #endif
 #if defined(MBEDTLS_ECP_C)
     if( mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECKEY ||
@@ -27,8 +32,30 @@
         mbedtls_pk_get_type( pk ) == MBEDTLS_PK_ECDSA )
     {
         int ret;
+        mbedtls_ecp_group_id curve;
+        switch( size )
+        {
+            case 0:
+            case 192:
+                curve = MBEDTLS_ECP_DP_SECP192R1;
+                break;
+            case 224:
+                curve = MBEDTLS_ECP_DP_SECP224R1;
+                break;
+            case 256:
+                curve = MBEDTLS_ECP_DP_SECP256R1;
+                break;
+            case 384:
+                curve = MBEDTLS_ECP_DP_SECP384R1;
+                break;
+            case 521:
+                curve = MBEDTLS_ECP_DP_SECP521R1;
+                break;
+            default:
+                return( -1 );
+        }
         if( ( ret = mbedtls_ecp_group_load( &mbedtls_pk_ec( *pk )->grp,
-                                      MBEDTLS_ECP_DP_SECP192R1 ) ) != 0 )
+                                            curve ) ) != 0 )
             return( ret );
 
         return mbedtls_ecp_gen_keypair( &mbedtls_pk_ec( *pk )->grp, &mbedtls_pk_ec( *pk )->d,
@@ -77,7 +104,7 @@
     mbedtls_pk_init( &pk );
 
     TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
-    TEST_ASSERT( pk_genkey( &pk ) == 0 );
+    TEST_ASSERT( pk_genkey( &pk, size ) == 0 );
 
     TEST_ASSERT( (int) mbedtls_pk_get_type( &pk ) == type );
     TEST_ASSERT( mbedtls_pk_can_do( &pk, type ) );
@@ -252,7 +279,7 @@
     memset( sig, 0, sizeof sig );
 
     TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
-    TEST_ASSERT( pk_genkey( &pk ) == 0 );
+    TEST_ASSERT( pk_genkey( &pk, 0 ) == 0 );
 
     TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, sizeof hash,
                           sig, &sig_len, rnd_std_rand, NULL ) == sign_ret );
@@ -447,7 +474,7 @@
     /* Initiliaze PK RSA context with random key */
     TEST_ASSERT( mbedtls_pk_setup( &rsa,
                               mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == 0 );
-    TEST_ASSERT( pk_genkey( &rsa ) == 0 );
+    TEST_ASSERT( pk_genkey( &rsa, RSA_KEY_SIZE ) == 0 );
 
     /* Extract key to the raw rsa context */
     TEST_ASSERT( mbedtls_rsa_copy( &raw, mbedtls_pk_rsa( rsa ) ) == 0 );
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index c43ef20..46c8bf9 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -44,7 +44,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
@@ -86,7 +87,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &N, radix_N, input_N ) == 0 );
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
@@ -127,7 +129,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
@@ -192,7 +195,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
@@ -256,7 +260,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
@@ -294,7 +299,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
@@ -342,7 +348,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );
 
@@ -381,7 +388,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, NULL, NULL, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_check_pubkey( &ctx ) == 0 );
 
 
@@ -440,7 +448,8 @@
     TEST_ASSERT( mbedtls_mpi_read_string( &E, radix_E, input_E ) == 0 );
 
     TEST_ASSERT( mbedtls_rsa_import( &ctx, &N, &P, &Q, NULL, &E ) == 0 );
-    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod / 8 ) );
+    TEST_ASSERT( mbedtls_rsa_get_bitlen( &ctx ) == (size_t) mod );
+    TEST_ASSERT( mbedtls_rsa_get_len( &ctx ) == (size_t) ( mod + 7 ) / 8 );
     TEST_ASSERT( mbedtls_rsa_complete( &ctx ) == 0 );
     TEST_ASSERT( mbedtls_rsa_check_privkey( &ctx ) == 0 );