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 );
}
/*