ECDSA: Refactor mbedtls_ecdsa_signature_to_raw

Change mbedtls_ecdsa_signature_to_raw so that it does not use MPI.
Add documentation changes.
diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h
index bff30fc..2b25aa6 100644
--- a/include/mbedtls/ecdsa.h
+++ b/include/mbedtls/ecdsa.h
@@ -256,8 +256,8 @@
  */
 int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
                             size_t ssize, uint16_t byte_len,
-                            unsigned char *buf, size_t bufsize,
-                            size_t* buflen );
+                            unsigned char *buf, size_t* buflen,
+                            size_t bufsize );
 /**
  * \brief           Convert a signature from numbers to ASN.1
  *
diff --git a/include/mbedtls/pkcs11_client.h b/include/mbedtls/pkcs11_client.h
index 97b4291..ac858f9 100644
--- a/include/mbedtls/pkcs11_client.h
+++ b/include/mbedtls/pkcs11_client.h
@@ -4,7 +4,7 @@
  * \brief Generic wrapper for Cryptoki (PKCS#11) support
  */
 /*
- *  Copyright (C) 2017, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2017-2018, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -70,10 +70,9 @@
  * \return              0 on success,
  *                      or MBEDTLS_ERR_PK_XXX error code.
  *
- * \note                The session and the key(s) must remain valid until the
- *                      PK context is closed with mbedtls_pk_free(). As an
- *                      exception, it's ok to call mbedtls_pk_free() itself
- *                      even if the Cryptoki handles have become invalid.
+ * \note                If any of the handles become invalid, then you may no
+ *                      longer do anything with the pk object except call
+ *                      mbedtls_pk_free on it.
  */
 int mbedtls_pkcs11_setup_pk( mbedtls_pk_context *ctx,
                              CK_SESSION_HANDLE hSession,
@@ -110,7 +109,7 @@
  *                      - #MBEDTLS_PK_FLAG_VERIFY: if set, the public key
  *                        will be authorized for verification.
  *                      - #MBEDTLS_PK_FLAG_DECRYPT: if set, the private key
- *                        will be authorized for signing.
+ *                        will be authorized for decryption.
  *                      - #MBEDTLS_PK_FLAG_ENCRYPT: if set, the public key
  *                        will be authorized for encryption.
  *
diff --git a/library/ecdsa.c b/library/ecdsa.c
index dba303b..7c8733e 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -291,60 +291,78 @@
  */
 int mbedtls_ecdsa_signature_to_raw( const unsigned char *sig,
                             size_t ssize, uint16_t byte_len,
-                            unsigned char *buf, size_t bufsize,
-                            size_t* buflen )
+                            unsigned char *buf, size_t* buflen,
+                            size_t bufsize)
 {
     int ret;
     unsigned char *p = (unsigned char *) sig;
+    unsigned char *buf_ptr;
     const unsigned char *end = sig + ssize;
-    size_t len;
-    mbedtls_mpi r, s;
+    size_t len, bytes_skipped, i;
 
     if( 2 * byte_len > bufsize )
     {
         return (MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
     }
 
-    mbedtls_mpi_init( &r );
-    mbedtls_mpi_init( &s );
-
     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
     {
         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-        goto cleanup;
+        return ret;
     }
 
     if( p + len != end )
     {
-        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
-        goto cleanup;
     }
 
-    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
-        ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
-    {
-        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-        goto cleanup;
-    }
-    p = (unsigned char *) buf;
-    if( ( ret = mbedtls_mpi_write_binary( &r, p, byte_len) ) )
-    {
-        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-        goto cleanup;
-    }
-    p += byte_len;
-    if( ( ret = mbedtls_mpi_write_binary( &s, p, byte_len) ) )
-    {
-        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-        goto cleanup;
-    }
-    *buflen = 2*byte_len;
+    /*
+     * Step 1: write R
+     */
+    buf_ptr = buf;
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+            return( ret );
 
-cleanup:
-    mbedtls_mpi_free( &r );
-    mbedtls_mpi_free( &s );
+    for( bytes_skipped = 0; bytes_skipped < len; bytes_skipped++ )
+            if( p[bytes_skipped] != 0 )
+                break;
+
+    if( len - bytes_skipped > bufsize )
+    {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    *buflen = len - bytes_skipped;
+
+    for( i = bytes_skipped; i < len; i++ )
+    {
+        buf_ptr[i - bytes_skipped] = p[i];
+    }
+    p += len;
+    buf_ptr += *buflen;
+
+    /*
+     * Step 2: write S
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+                return( ret );
+
+    for( bytes_skipped = 0; bytes_skipped < len; bytes_skipped++ )
+            if( p[bytes_skipped] != 0 )
+                break;
+
+    if( len - bytes_skipped + *buflen > bufsize )
+    {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    *buflen += len - bytes_skipped;
+
+    for( i = bytes_skipped; i < len; i++ )
+    {
+        buf_ptr[i - bytes_skipped] = p[i];
+    }
 
     return( ret );
 }
diff --git a/library/pkcs11_client.c b/library/pkcs11_client.c
index cb803cd..b328d8c 100644
--- a/library/pkcs11_client.c
+++ b/library/pkcs11_client.c
@@ -1,7 +1,7 @@
 /*
  *  Generic wrapper for Cryptoki (PKCS#11) support
  *
- *  Copyright (C) 2017, ARM Limited, All Rights Reserved
+ *  Copyright (C) 2017-2018, ARM Limited, All Rights Reserved
  *  SPDX-License-Identifier: Apache-2.0
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -292,8 +292,8 @@
             return( MBEDTLS_ERR_PK_ALLOC_FAILED );
         }
         if( mbedtls_ecdsa_signature_to_raw( sig, sig_len, byte_len,
-                                    decoded_sig, 2 * byte_len,
-                                    &decoded_sig_len ) != 0 )
+                                    decoded_sig, &decoded_sig_len,
+                                    2 * byte_len ) != 0 )
         {
             rv = CKR_GENERAL_ERROR;
             goto exit;