aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/crypto/bigint.c47
-rw-r--r--src/include/ipxe/bigint.h13
2 files changed, 60 insertions, 0 deletions
diff --git a/src/crypto/bigint.c b/src/crypto/bigint.c
index e5e6e2f12..dd75cd9d1 100644
--- a/src/crypto/bigint.c
+++ b/src/crypto/bigint.c
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
#include <assert.h>
+#include <stdio.h>
#include <ipxe/profile.h>
#include <ipxe/bigint.h>
@@ -38,6 +39,52 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static struct profiler bigint_mod_profiler __profiler =
{ .name = "bigint_mod" };
+/** Minimum number of least significant bytes included in transcription */
+#define BIGINT_NTOA_LSB_MIN 16
+
+/**
+ * Transcribe big integer (for debugging)
+ *
+ * @v value0 Element 0 of big integer to be transcribed
+ * @v size Number of elements
+ * @ret string Big integer in string form (may be abbreviated)
+ */
+const char * bigint_ntoa_raw ( const bigint_element_t *value0,
+ unsigned int size ) {
+ const bigint_t ( size ) __attribute__ (( may_alias ))
+ *value = ( ( const void * ) value0 );
+ bigint_element_t element;
+ static char buf[256];
+ unsigned int count;
+ int threshold;
+ uint8_t byte;
+ char *tmp;
+ int i;
+
+ /* Calculate abbreviation threshold, if any */
+ count = ( size * sizeof ( element ) );
+ threshold = count;
+ if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) {
+ threshold -= ( ( sizeof ( buf ) - 3 /* "..." */
+ - ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ )
+ - 1 /* NUL */ ) / 2 /* "xx" */ );
+ }
+
+ /* Transcribe bytes, abbreviating with "..." if necessary */
+ for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) {
+ element = value->element[ i / sizeof ( element ) ];
+ byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) );
+ tmp += sprintf ( tmp, "%02x", byte );
+ if ( i == threshold ) {
+ tmp += sprintf ( tmp, "..." );
+ i = BIGINT_NTOA_LSB_MIN;
+ }
+ }
+ assert ( tmp < ( buf + sizeof ( buf ) ) );
+
+ return buf;
+}
+
/**
* Conditionally swap big integers (in constant time)
*
diff --git a/src/include/ipxe/bigint.h b/src/include/ipxe/bigint.h
index 2dd99380d..1cc606b89 100644
--- a/src/include/ipxe/bigint.h
+++ b/src/include/ipxe/bigint.h
@@ -41,6 +41,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
/**
+ * Transcribe big integer (for debugging)
+ *
+ * @v value Big integer to be transcribed
+ * @ret string Big integer in string form (may be abbreviated)
+ */
+#define bigint_ntoa( value ) ( { \
+ unsigned int size = bigint_size (value); \
+ bigint_ntoa_raw ( (value)->element, size ); \
+ } )
+
+/**
* Initialise big integer
*
* @v value Big integer to initialise
@@ -360,6 +371,8 @@ bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) {
return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
}
+const char * bigint_ntoa_raw ( const bigint_element_t *value0,
+ unsigned int size );
void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
const void *data, size_t len );
void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,