I'm using HPUX 11.23, Itanium, openssl-0.9.8d, cc 6.10
I seem to have found a contradiction in the build environment and I
don't think it is specific to HPUX, but rather to platforms who have a
64bit 'long long' and require a "%ll" to print them.
What we want to build is a 32bit binary build using 64bit longs -- i.e.,
long long. The build actually passes the make test, but a simple test
program exercising bn2dec() fails with what looks like a 64bit value
truncated to 32bit. We're using the default build flags for
hpux-ia64-cc
This test program shows that the 64bit value is truncated in the string
generation:
Output --
Input bytes: 255,255,255,255,255,
Input size (bytes): 5
BIGNUM top: 1
BIGNUM dmax: 1
BIGNUM neg: 0
BIGNUM flags: 1
BIGNUM bit chunks: 0x000000ffffffffff,
String Format: 4294967295
Source --
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/dh.h>
#include <string.h>
int main(int argc, char* argv[])
{
#define NUM_LENGTH sizeof(num)
const unsigned char num[5] = {255, 255, 255, 255, 255};
printf("Input bytes: ");
for (int i = 0; i < NUM_LENGTH; ++i)
{
printf("%d,", num[i]);
}
printf("\n");
printf("Input size (bytes): %d\n", NUM_LENGTH);
BIGNUM* keyNum = BN_bin2bn(num, NUM_LENGTH, 0);
printf("BIGNUM top: %d\n", keyNum->top);
printf("BIGNUM dmax: %d\n", keyNum->dmax);
printf("BIGNUM neg: %d\n", keyNum->neg);
printf("BIGNUM flags: %d\n", keyNum->flags);
printf("BIGNUM bit chunks: ");
for (int k = 0; k < keyNum->top; ++k)
{
printf("0x%016llx,", keyNum->d[k]);
}
printf("\n");
char* decBuf = 0;
decBuf = BN_bn2dec(keyNum);
printf("String Format: %s\n", decBuf);
return 0;
}
Tracing through the openssl code I found that BIO_snprintf() is the
problem (substituting libc's native vsnprintf() fixes the problem):
b_print.c's _dopr() uses a 32bit variable (called value) as the lvalue
to the var_arg(args, long long) call causing the truncation. But
'value' is declared as a LLONG. Backtracing through the code, LLONG is
defined as 'long long' if BN_LLONG is defined (otherwise it is simply a
long). But when you define SIXTY_FOUR_BIT, BN_LLONG is explicitly
UNDEFINED. And as far as I can tell, SIXTY_FOUR_BIT is required in
order to get BN_DEC_FMT1/FMT2 to be defined as %ll's and not %l. Hence
a contradiction...
The safest workaround for now seems to just have BI_snprintf() call the
native vsnprintf().
If someone needs a test system, one can usually be accessed via
http://www.testdrive.hp.com/. I can try to help expedite the
application process if necessary.
------------------------- snippets from b_print.c
[...]
#ifdef BN_LLONG
# ifndef HAVE_LONG_LONG
# define HAVE_LONG_LONG 1
# endif
#endif
[...]
#if HAVE_LONG_LONG
# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
# define LLONG _int64
# else
# define LLONG long long
# endif
#else
#define LLONG long
#endif
[...]
static void
_dopr(
char **sbuffer,
char **buffer,
size_t *maxlen,
size_t *retlen,
int *truncated,
const char *format,
va_list args)
{
char ch;
LLONG value; <<<<<<<<<<
LDOUBLE fvalue;
char *strvalue;
int min;
int max;
int state;
int flags;
int cflags;
size_t currlen;
[...]
case DP_C_LLONG:
value = va_arg(args, unsigned LLONG); <<<<<<<<<
break;
default:
------------------------- bn.h
/* This is where the long long data type is 64 bits, but long is 32.
* For machines where there are 64bit registers, this is the mode to use.
* IRIX, on R4000 and above should use this mode, along with the relevant
* assembler code :-). Do NOT define BN_LLONG.
*/
#ifdef SIXTY_FOUR_BIT
#undef BN_LLONG <<<<<<<<<<<<<<<<<<<<<<<
#undef BN_ULLONG
#define BN_ULONG unsigned long long
#define BN_LONG long long
#define BN_BITS 128
#define BN_BYTES 8
#define BN_BITS2 64
#define BN_BITS4 32
#define BN_MASK2 (0xffffffffffffffffLL)
#define BN_MASK2l (0xffffffffL)
#define BN_MASK2h (0xffffffff00000000LL)
#define BN_MASK2h1 (0xffffffff80000000LL)
#define BN_TBIT (0x8000000000000000LL)
#define BN_DEC_CONV (10000000000000000000ULL)
#define BN_DEC_FMT1 "%llu"
#define BN_DEC_FMT2 "%019llu"
#define BN_DEC_NUM 19
#endif
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]