From: "Arpadffy Zoltan via RT" <r...@openssl.org>

> test BN_mont
> Montgomery multiplication test failed!

   This seems to be caused by an apparently prevalent belief that the
way to do integer operations on a pointer is to type-cast that pointer
to size_t.  Sadly, on VMS, size_t is 32 bits (unsigned int), regardless
of the pointer size, so that, with 64-bit pointers, code like, for
example, the following (from "crypto/bn/bn_mont.c") fails:

[...]
        BN_ULONG *ap,*np,*rp,n0,v,*nrp;
[...]
        nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
[...]

My ignorance of the algorithms involved is great, but I'd guess that
"crypto/bn/bn_nist.c" suffers from a lot of this stuff, too.  A global
search for "(size_t)" finds many suspicious applications of "(size_t)"
to pointers (and a bunch of loose variables declared as "size_t" which
might be better as something else, too).

   What seems (to me) to be needed in these cases is some macro or
typedef which is an integer whose size is reliably the same as that of a
pointer, which size_t is not.  For testing, I've inserted this into
"crypto/bn/bn.h":

#if defined(OPENSSL_SYS_VMS)
# if __INITIAL_POINTER_SIZE == 64
#  define PTR_SIZE_INT long long
# else /* __INITIAL_POINTER_SIZE == 64 */
#  define PTR_SIZE_INT int
# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
#else /* defined(OPENSSL_SYS_VMS) */
# define PTR_SIZE_INT size_t
#endif /* defined(OPENSSL_SYS_VMS) [else] */

and then substituted "PTR_SIZE_INT" for "size_t", where (I thought)
appropriate, in "crypto/bn/bn_mont.c" and "crypto/bn/bn_nist.c".  I
suspect that more code in more places could use changes like these, but
these changes, along with a bunch of other, more VMS-specific builder
and code changes, seem to clear the compiler complaints and test
failures.  (Is "size_t" really a good choice everywhere else?)  I didn't
look beyond "crypto/bn", but if this kind of thing is done elsewhere,
too, then it would probably make more sense to get this thing
established at a higher level than "crypto/bn/bn.h".

   Speaking of other VMS-specific builder and code changes, why is this
product being built with the highly restrictive C compiler option
/STANDARD=ANSI89 instead of the default, /STANDARD=RELAXED?  The
VMS-specific gmtime()-replacement code (in "crypto/o_time.c") depends on
32-bit pointers.  (It also appears to be sub-optimal.  For example, when
is "logvalue" calculated?  Always.  When is it used?  Sometimes.)  The
gmtime() in the C RTL (since VMS V7.0) seems to work with pointers of
either size, but it's not visible with /STANDARD=ANSI89 (which defines
_ANSI_C_SOURCE).   Rather than try to fix the old VMS-specific
gmtime()-replacement code, I just started using the existing
gmtime()-using code, and saying:
      USER_CCFLAGS == "/STANDARD=RELAXED"
before running the builder.  I didn't see any problems from that.  (And
it would probably allow tossing all that junk which is currently needed
to suppress compiler complaints like %CC-I-DOLLARID (and others?).)

   I don't know where or how anyone would like to add the
pointer-sized-integer macro/typedef/whatever, so I didn't try to find
and fix every place where it ought to be used.  If someone could decide
how to do that, then I could revise, collect, and submit my suggested
changes.  (Most of which, if experience is any guide, would probably
then vanish without a trace, but that doesn't seem to have stopped me
yet.)

------------------------------------------------------------------------

   Steven M. Schweda               sms@antinode-info
   382 South Warwick Street        (+1) 651-699-9818
   Saint Paul  MN  55105-2547
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to