Merge pull request #314 from gilles-peskine-arm/pkwrite_ECPrivateKey_size-crypto
Fix pk_write with EC key to use a constant size for the private value
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 4388160..c2c5623 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -38,7 +38,9 @@
#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/bignum.h"
#include "mbedtls/ecp.h"
+#include "mbedtls/platform_util.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
#include "mbedtls/ecdsa.h"
@@ -154,6 +156,26 @@
return( (int) len );
}
+
+/*
+ * privateKey OCTET STRING -- always of length ceil(log2(n)/8)
+ */
+static int pk_write_ec_private( unsigned char **p, unsigned char *start,
+ mbedtls_ecp_keypair *ec )
+{
+ int ret;
+ size_t byte_length = ( ec->grp.pbits + 7 ) / 8;
+ unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
+
+ ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length );
+ if( ret != 0 )
+ goto exit;
+ ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length );
+
+exit:
+ mbedtls_platform_zeroize( tmp, byte_length );
+ return( ret );
+}
#endif /* MBEDTLS_ECP_C */
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
@@ -424,9 +446,8 @@
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
len += par_len;
- /* privateKey: write as MPI then fix tag */
- MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) );
- *c = MBEDTLS_ASN1_OCTET_STRING;
+ /* privateKey */
+ MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_private( &c, buf, ec ) );
/* version */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
diff --git a/tests/data_files/ec_256_long_prv.pem b/tests/data_files/ec_256_long_prv.pem
new file mode 100644
index 0000000..5141e30
--- /dev/null
+++ b/tests/data_files/ec_256_long_prv.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIIcex4mqXsQamUKTVf8vXmTAJrQvGjh5mXG8p9+OR4xAoAoGCCqGSM49
+AwEHoUQDQgAEqJ2HQjPpc6fDwE/vSa6U35USXawkTo98y4U6NsAl+rOGuqMPEFXf
+P1Srm/Jrzwa/RuppRL5kgyAsGJTUmwZEzQ==
+-----END EC PRIVATE KEY-----
diff --git a/tests/data_files/ec_521_short_prv.pem b/tests/data_files/ec_521_short_prv.pem
new file mode 100644
index 0000000..427b7ad
--- /dev/null
+++ b/tests/data_files/ec_521_short_prv.pem
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIAOXdk7W+Hf5L7Hc9fKe44wmpaRNs5ERFTkv5CrlXv/Bu3y28M673q
+vBNo7a/UE/6NNQHu2pQODEYFpMg6R34b5SigBwYFK4EEACOhgYkDgYYABAFUMHXV
+KPA4vkMgq+pFgDoH96XoM517gF2GJFV6h2gLhykzIHL/otAyEpAStw7MBvbU0V21
+ixB+hjqzO7Snxaj9mwB8g87OKxm5eGfsqvJNPdJ0RZ/EKy06Ukg6KThlhQeyrtIk
+g5PTCrPnNszlffAy6/jCOe3Moi59g15H13sSzwfX6g==
+-----END EC PRIVATE KEY-----
diff --git a/tests/suites/test_suite_pkwrite.data b/tests/suites/test_suite_pkwrite.data
index c8ff177..e0101cc 100644
--- a/tests/suites/test_suite_pkwrite.data
+++ b/tests/suites/test_suite_pkwrite.data
@@ -30,10 +30,18 @@
depends_on:MBEDTLS_ECP_C:MBEDTLS_BASE64_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED
pk_write_key_check:"data_files/ec_prv.sec1.pem"
+Private key write check EC 256 bits (top bit set)
+depends_on:MBEDTLS_ECP_C:MBEDTLS_BASE64_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+pk_write_key_check:"data_files/ec_256_long_prv.pem"
+
Private key write check EC 521 bits
depends_on:MBEDTLS_ECP_C:MBEDTLS_BASE64_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED
pk_write_key_check:"data_files/ec_521_prv.pem"
+Private key write check EC 521 bits (top byte is 0)
+depends_on:MBEDTLS_ECP_C:MBEDTLS_BASE64_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED
+pk_write_key_check:"data_files/ec_521_short_prv.pem"
+
Private key write check EC Brainpool 512 bits
depends_on:MBEDTLS_ECP_C:MBEDTLS_BASE64_C:MBEDTLS_ECP_DP_BP512R1_ENABLED
pk_write_key_check:"data_files/ec_bp512_prv.pem"