ECDSA: Add mbedtls_raw_ecdsa_signature_to_asn1 without MPI usage
Refactor mbedtls_ecdsa_signature_to_raw to allow overlapping buffers
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 7c8733e..6be57d5 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -298,7 +298,7 @@
unsigned char *p = (unsigned char *) sig;
unsigned char *buf_ptr;
const unsigned char *end = sig + ssize;
- size_t len, bytes_skipped, i;
+ size_t len, bytes_skipped;
if( 2 * byte_len > bufsize )
{
@@ -335,10 +335,7 @@
}
*buflen = len - bytes_skipped;
- for( i = bytes_skipped; i < len; i++ )
- {
- buf_ptr[i - bytes_skipped] = p[i];
- }
+ memmove(buf_ptr, &p[bytes_skipped], *buflen);
p += len;
buf_ptr += *buflen;
@@ -358,11 +355,7 @@
}
*buflen += len - bytes_skipped;
-
- for( i = bytes_skipped; i < len; i++ )
- {
- buf_ptr[i - bytes_skipped] = p[i];
- }
+ memmove(buf_ptr, &p[bytes_skipped], len - bytes_skipped);
return( ret );
}
@@ -389,6 +382,76 @@
*slen = len;
return( 0 );
+ }
+
+int mbedtls_raw_ecdsa_signature_to_asn1( const unsigned char *r,
+ const unsigned char *s, uint16_t num_len,
+ unsigned char *sig, size_t *slen, size_t ssize )
+{
+ int ret;
+ unsigned char *p = sig + ssize;
+ size_t total_len = 0;
+ size_t padding_len = 0;
+
+ /*
+ * Step 1: write S
+ */
+ memmove( p - num_len, s, num_len );
+ p -= num_len;
+ total_len += num_len;
+ if( *p & 0x80 )
+ {
+ if( p - sig < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ *--p = 0x00;
+ padding_len += 1;
+ }
+ total_len += padding_len;
+
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig,
+ num_len + padding_len ) );
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
+ MBEDTLS_ASN1_INTEGER ) );
+
+ padding_len = 0;
+
+ /*
+ * Step 2: write R
+ */
+ memmove( p - num_len, r, num_len );
+ p -= num_len;
+ total_len += num_len;
+ if( *p & 0x80 )
+ {
+ if( p - sig < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ *--p = 0x00;
+ padding_len += 1;
+ }
+ total_len += padding_len;
+
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig,
+ num_len + padding_len ) );
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
+ MBEDTLS_ASN1_INTEGER ) );
+
+ /*
+ * Step 3: write rest of the data
+ */
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_len( &p, sig, total_len ) );
+ MBEDTLS_ASN1_CHK_ADD( total_len, mbedtls_asn1_write_tag( &p, sig,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+ /*
+ * Step 4: move to the beginning of the buffer, zeroize the rest
+ */
+ memmove( sig, p, total_len );
+ memset( sig + total_len, 0, ssize - total_len );
+ *slen = total_len;
+
+ return( 0 );
}
/*
diff --git a/library/pkcs11_client.c b/library/pkcs11_client.c
index b328d8c..439c50c 100644
--- a/library/pkcs11_client.c
+++ b/library/pkcs11_client.c
@@ -191,9 +191,7 @@
*/
uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
size_t sig_size = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length );
- mbedtls_mpi r, s;
- mbedtls_mpi_init( &r );
- mbedtls_mpi_init( &s );
+
rv = CKR_OK;
if( ck_sig_len != 2 * byte_len )
{
@@ -201,22 +199,15 @@
rv = CKR_GENERAL_ERROR;
goto ecdsa_exit;
}
- if( mbedtls_mpi_read_binary( &r, sig, byte_len ) != 0 ||
- mbedtls_mpi_read_binary( &s, sig + byte_len, byte_len ) != 0 )
- {
- rv = CKR_HOST_MEMORY;
- goto ecdsa_exit;
- }
+
/* The signature buffer is guaranteed to have enough room for
the encoded signature by the pk_sign interface. */
- if( mbedtls_ecdsa_signature_to_asn1( &r, &s, sig, sig_len, sig_size ) != 0 )
+ if( mbedtls_raw_ecdsa_signature_to_asn1( sig, sig + byte_len, byte_len, sig, sig_len, sig_size ) != 0 )
{
rv = CKR_GENERAL_ERROR;
goto ecdsa_exit;
}
ecdsa_exit:
- mbedtls_mpi_free( &r );
- mbedtls_mpi_free( &s );
if( rv != CKR_OK )
goto exit;
}