From c77aa89206d633aa8218e245babb98ac195281e2 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 29 Nov 2016 05:28:17 +0300 Subject: Add support for I/O of little-endian MPI Signed-off-by: Dmitry Eremin-Solenikov --- lib/mpi.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 12 deletions(-) (limited to 'lib/mpi.c') diff --git a/lib/mpi.c b/lib/mpi.c index afe1c0ea7d..5dbcfb4069 100644 --- a/lib/mpi.c +++ b/lib/mpi.c @@ -153,6 +153,28 @@ _gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes) return 0; } +int +_gnutls_mpi_init_scan_le(bigint_t * ret_mpi, const void *buffer, size_t nbytes) +{ + bigint_t r; + int ret; + + ret = _gnutls_mpi_init(&r); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_mpi_scan_le(r, buffer, nbytes); + if (ret < 0) { + gnutls_assert(); + _gnutls_mpi_release(&r); + return ret; + } + + *ret_mpi = r; + + return 0; +} + /* Always has the first bit zero */ int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest) { @@ -248,13 +270,18 @@ _gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest, return 0; } +/* Flags for __gnutls_x509_read_int() and __gnutls_x509_write_int */ +#define GNUTLS_X509_INT_OVERWRITE (1 << 0) +#define GNUTLS_X509_INT_LE (1 << 1) +#define GNUTLS_X509_INT_LZ (1 << 2) /* write only */ + /* this function reads an integer * from asn1 structs. Combines the read and mpi_scan * steps. */ static int __gnutls_x509_read_int(ASN1_TYPE node, const char *value, - bigint_t * ret_mpi, int overwrite) + bigint_t * ret_mpi, unsigned int flags) { int result; uint8_t *tmpstr = NULL; @@ -280,9 +307,14 @@ __gnutls_x509_read_int(ASN1_TYPE node, const char *value, return _gnutls_asn2err(result); } - result = _gnutls_mpi_init_scan(ret_mpi, tmpstr, tmpstr_size); + if (flags & GNUTLS_X509_INT_LE) + result = _gnutls_mpi_init_scan_le(ret_mpi, tmpstr, + tmpstr_size); + else + result = _gnutls_mpi_init_scan(ret_mpi, tmpstr, + tmpstr_size); - if (overwrite) + if (flags & GNUTLS_X509_INT_OVERWRITE) zeroize_key(tmpstr, tmpstr_size); gnutls_free(tmpstr); @@ -298,29 +330,42 @@ int _gnutls_x509_read_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { - return __gnutls_x509_read_int(node, value, ret_mpi, 0); + return __gnutls_x509_read_int(node, value, ret_mpi, + 0); } int _gnutls_x509_read_key_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { - return __gnutls_x509_read_int(node, value, ret_mpi, 1); + return __gnutls_x509_read_int(node, value, ret_mpi, + GNUTLS_X509_INT_OVERWRITE); +} + +int +_gnutls_x509_read_key_int_le(ASN1_TYPE node, const char *value, + bigint_t * ret_mpi) +{ + return __gnutls_x509_read_int(node, value, ret_mpi, + GNUTLS_X509_INT_OVERWRITE | + GNUTLS_X509_INT_LE); } /* Writes the specified integer into the specified node. */ static int __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, - int lz, int overwrite) + unsigned int flags) { uint8_t *tmpstr; size_t s_len; int result; s_len = 0; - if (lz) + if (flags & GNUTLS_X509_INT_LZ) result = _gnutls_mpi_print_lz(mpi, NULL, &s_len); + else if (GNUTLS_X509_INT_LE) + result = _gnutls_mpi_print_le(mpi, NULL, &s_len); else result = _gnutls_mpi_print(mpi, NULL, &s_len); @@ -335,8 +380,10 @@ __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, return GNUTLS_E_MEMORY_ERROR; } - if (lz) + if (flags & GNUTLS_X509_INT_LZ) result = _gnutls_mpi_print_lz(mpi, tmpstr, &s_len); + else if (GNUTLS_X509_INT_LE) + result = _gnutls_mpi_print_le(mpi, tmpstr, &s_len); else result = _gnutls_mpi_print(mpi, tmpstr, &s_len); @@ -347,8 +394,8 @@ __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, } result = asn1_write_value(node, value, tmpstr, s_len); - - if (overwrite) + + if (flags & GNUTLS_X509_INT_OVERWRITE) zeroize_key(tmpstr, s_len); gnutls_free(tmpstr); @@ -365,12 +412,23 @@ int _gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { - return __gnutls_x509_write_int(node, value, mpi, lz, 0); + return __gnutls_x509_write_int(node, value, mpi, + lz ? GNUTLS_X509_INT_LZ : 0); } int _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { - return __gnutls_x509_write_int(node, value, mpi, lz, 1); + return __gnutls_x509_write_int(node, value, mpi, + (lz ? GNUTLS_X509_INT_LZ : 0) | + GNUTLS_X509_INT_OVERWRITE); +} + +int +_gnutls_x509_write_key_int_le(ASN1_TYPE node, const char *value, bigint_t mpi) +{ + return __gnutls_x509_write_int(node, value, mpi, + GNUTLS_X509_INT_OVERWRITE | + GNUTLS_X509_INT_LE); } -- cgit v1.2.1