Import ncpfs 2.0.12
This commit is contained in:
25
lib/Makefile
25
lib/Makefile
@@ -19,6 +19,15 @@ endif
|
||||
|
||||
CFLAGS += $(PIC_FLAG)
|
||||
|
||||
ifdef NDS_SUPPORT
|
||||
CFLAGS += -DNDS_SUPPORT
|
||||
NDS_OBJ = ndslib.o mpilib.o ndscrypt.o
|
||||
endif
|
||||
ifdef SIGNATURES
|
||||
CFLAGS += -DSIGNATURES
|
||||
SIGN_OBJ = ncpsign.o
|
||||
endif
|
||||
|
||||
default:
|
||||
make -C ..
|
||||
|
||||
@@ -27,8 +36,17 @@ all: libcom_err.a ncplib_err.o $(NCP_LIB)
|
||||
install:
|
||||
$(INSTALL_LIB)
|
||||
|
||||
mpilib.o: mpilib.c
|
||||
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c mpilib.c
|
||||
ndscrypt.o: ndscrypt.c
|
||||
$(CC) $(CFLAGS) -c ndscrypt.c
|
||||
ndslib.o: ndslib.c
|
||||
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c ndslib.c
|
||||
|
||||
ncpsign.o: ncpsign.c
|
||||
$(CC) $(CFLAGS) -c ncpsign.c
|
||||
ncplib.o: ncplib.c ncplib_err.h
|
||||
$(CC) $(CFLAGS) -c ncplib.c
|
||||
$(CC) $(CFLAGS) -c ncplib.c
|
||||
|
||||
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
|
||||
com_err/init_et.c
|
||||
@@ -38,8 +56,9 @@ COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \
|
||||
libcom_err.a: $(COM_ERR_CFILES)
|
||||
make -C com_err
|
||||
|
||||
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a
|
||||
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(COM_ERR_OFILES)
|
||||
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a $(SIGN_OBJ) $(NDS_OBJ)
|
||||
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(SIGN_OBJ) \
|
||||
$(COM_ERR_OFILES) $(NDS_OBJ)
|
||||
ln -sf libncp.so.1.0 libncp.so.1
|
||||
ln -sf libncp.so.1 libncp.so
|
||||
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH
|
||||
|
||||
1881
lib/mpilib.c
Normal file
1881
lib/mpilib.c
Normal file
File diff suppressed because it is too large
Load Diff
468
lib/mpilib.h
Normal file
468
lib/mpilib.h
Normal file
@@ -0,0 +1,468 @@
|
||||
/* C include file for MPI multiprecision integer math routines.
|
||||
|
||||
Boulder Software Engineering
|
||||
3021 Eleventh Street
|
||||
Boulder, CO 80304
|
||||
(303) 541-0140
|
||||
|
||||
(c) Copyright 1986-92 by Philip Zimmermann. All rights reserved.
|
||||
The author assumes no liability for damages resulting from the use
|
||||
of this software, even if the damage results from defects in this
|
||||
software. No warranty is expressed or implied.
|
||||
|
||||
These routines implement all of the multiprecision arithmetic necessary
|
||||
for Rivest-Shamir-Adleman (RSA) public key cryptography, as well as
|
||||
other number-theoretic algorithms such as ElGamal, Diffie-Hellman,
|
||||
or Rabin.
|
||||
|
||||
Although originally developed in Microsoft C for the IBM PC, this code
|
||||
contains few machine dependencies. It assumes 2's complement
|
||||
arithmetic. It can be adapted to 8-bit, 16-bit, or 32-bit machines,
|
||||
lowbyte-highbyte order or highbyte-lowbyte order. This version
|
||||
has been converted to ANSI C.
|
||||
|
||||
Modified 8 Apr 92 - HAJK - Implement new VAX/VMS primitive support.
|
||||
Modified 29 Nov 92 - Thad Smith
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "usuals.h" /* typedefs for byte, word16, boolean, etc. */
|
||||
#include "platform.h" /* customization for different environments */
|
||||
|
||||
/* Platform customization:
|
||||
* A version which runs on almost any computer can be implemented by
|
||||
* defining PORTABLE and MPORTABLE, preferably as a command line
|
||||
* parameter. Faster versions can be generated by specifying specific
|
||||
* parameters, such as size of unit and MULTUNIT, and by supplying some
|
||||
* of the critical in assembly. See the file platform.h for more
|
||||
* details on customization.
|
||||
*
|
||||
* The symbol HIGHFIRST, designating that integers and longs are stored
|
||||
* with the most significant bit in the lowest address, should be defined
|
||||
* on the command line for compiling all files, since it is used by files
|
||||
* other than the mpilib routines.
|
||||
*/
|
||||
|
||||
#ifndef ALIGN
|
||||
#define ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef PEASANT /* if not Russian peasant modulo multiply algorithm */
|
||||
#ifndef MERRITT /* if not Merritt's modmult */
|
||||
#ifndef UPTON /* if not Upton's modmult */
|
||||
#ifndef SMITH
|
||||
#define SMITH /* default: use Smith's modmult algorithm */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SMITH
|
||||
#define UPTON_OR_SMITH /* enable common code */
|
||||
#endif
|
||||
#ifdef UPTON
|
||||
#define UPTON_OR_SMITH /* enable common code */
|
||||
#endif
|
||||
|
||||
#ifndef UNIT32
|
||||
#ifndef UNIT8
|
||||
#define UNIT16 /* default--use 16-bit units */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*** CAUTION: If your machine has an unusual word size that is not a
|
||||
power of 2 (8, 16, 32, or 64) bits wide, then the macros here that
|
||||
use the symbol "LOG_UNITSIZE" must be changed.
|
||||
***/
|
||||
|
||||
#ifdef UNIT8
|
||||
typedef unsigned char unit;
|
||||
typedef signed char signedunit;
|
||||
#define UNITSIZE 8 /* number of bits in a unit */
|
||||
#define LOG_UNITSIZE 3
|
||||
#define uppermostbit ((unit) 0x80)
|
||||
#define BYTES_PER_UNIT 1 /* number of bytes in a unit */
|
||||
#define units2bits(n) ((n) << 3) /* fast multiply by UNITSIZE */
|
||||
#define units2bytes(n) (n)
|
||||
#define bits2units(n) (((n)+7) >> 3)
|
||||
#define bytes2units(n) (n)
|
||||
#endif
|
||||
|
||||
#ifdef UNIT16
|
||||
typedef word16 unit;
|
||||
typedef short signedunit;
|
||||
#define UNITSIZE 16 /* number of bits in a unit */
|
||||
#define LOG_UNITSIZE 4
|
||||
#define uppermostbit ((unit) 0x8000)
|
||||
#define BYTES_PER_UNIT 2 /* number of bytes in a unit */
|
||||
#define units2bits(n) ((n) << 4) /* fast multiply by UNITSIZE */
|
||||
#define units2bytes(n) ((n) << 1)
|
||||
#define bits2units(n) (((n)+15) >> 4)
|
||||
#define bytes2units(n) (((n)+1) >> 1)
|
||||
#endif
|
||||
|
||||
#ifdef UNIT32
|
||||
typedef word32 unit;
|
||||
typedef long signedunit;
|
||||
#define UNITSIZE 32 /* number of bits in a unit */
|
||||
#define LOG_UNITSIZE 5
|
||||
#define uppermostbit ((unit) 0x80000000L)
|
||||
#define BYTES_PER_UNIT 4 /* number of bytes in a unit */
|
||||
#define units2bits(n) ((n) << 5) /* fast multiply by UNITSIZE */
|
||||
#define units2bytes(n) ((n) << 2)
|
||||
#define bits2units(n) (((n)+31) >> 5)
|
||||
#define bytes2units(n) (((n)+3) >> 2)
|
||||
#endif
|
||||
|
||||
#define power_of_2(b) ((unit) 1 << (b)) /* computes power-of-2 bit masks */
|
||||
#define bits2bytes(n) (((n)+7) >> 3)
|
||||
/* Some C compilers (like the ADSP2101) will not always collapse constant
|
||||
expressions at compile time if the expressions contain shift operators. */
|
||||
/* #define uppermostbit power_of_2(UNITSIZE-1) */
|
||||
/* #define UNITSIZE units2bits(1) */ /* number of bits in a unit */
|
||||
/* #define bytes2units(n) bits2units((n)<<3) */
|
||||
/* #define BYTES_PER_UNIT (UNITSIZE >> 3) */
|
||||
/* LOG_UNITSIZE is the log base 2 of UNITSIZE, ie: 4 for 16-bit units */
|
||||
/* #define units2bits(n) ((n) << LOG_UNITSIZE) */ /* fast multiply by UNITSIZE */
|
||||
/* #define units2bytes(n) ((n) << (LOG_UNITSIZE-3)) */
|
||||
/* #define bits2units(n) (((n)+(UNITSIZE-1)) >> LOG_UNITSIZE) */
|
||||
/* #define bytes2units(n) (((n)+(BYTES_PER_UNIT-1)) >> (LOG_UNITSIZE-3)) */
|
||||
|
||||
typedef unit *unitptr;
|
||||
|
||||
|
||||
/*--------------------- Byte ordering stuff -------------------*/
|
||||
#ifdef HIGHFIRST
|
||||
|
||||
/* these definitions assume MSB comes first */
|
||||
#define tohigher(n) (-(n)) /* offset towards higher unit */
|
||||
#define pre_higherunit(r) (--(r))
|
||||
#define pre_lowerunit(r) (++(r))
|
||||
#define post_higherunit(r) ((r)--)
|
||||
#define post_lowerunit(r) ((r)++)
|
||||
#define bit_index(n) (global_precision-bits2units((n)+1))
|
||||
#define lsbptr(r,prec) ((r)+(prec)-1)
|
||||
#define make_lsbptr(r,prec) (r) = lsbptr(r,prec)
|
||||
#define unmake_lsbptr(r,prec) (r) = ((r)-(prec)+1)
|
||||
#define msbptr(r,prec) (r)
|
||||
#define make_msbptr(r,prec) /* (r) = msbptr(r,prec) */
|
||||
|
||||
/* The macro rescale(r,current_precision,new_precision) rescales
|
||||
a multiprecision integer by adjusting r and its precision to new values.
|
||||
It can be used to reverse the effects of the normalize
|
||||
routine given above. See the comments in normalize concerning
|
||||
Intel vs. Motorola LSB/MSB conventions.
|
||||
WARNING: You can only safely call rescale on registers that
|
||||
you have previously normalized with the above normalize routine,
|
||||
or are known to be big enough for the new precision. You may
|
||||
specify a new precision that is smaller than the current precision.
|
||||
You must be careful not to specify a new_precision value that is
|
||||
too big, or which adjusts the r pointer out of range.
|
||||
*/
|
||||
#define rescale(r,currentp,newp) r -= ((newp) - (currentp))
|
||||
|
||||
/* The macro normalize(r,precision) "normalizes" a multiprecision integer
|
||||
by adjusting r and precision to new values. For Motorola-style processors
|
||||
(MSB-first), r is a pointer to the MSB of the register, and must
|
||||
be adjusted to point to the first nonzero unit. For Intel/VAX-style
|
||||
(LSB-first) processors, r is a pointer to the LSB of the register,
|
||||
and must be left unchanged. The precision counter is always adjusted,
|
||||
regardless of processor type. In the case of precision = 0,
|
||||
r becomes undefined.
|
||||
*/
|
||||
#define normalize(r,prec) \
|
||||
{ prec = significance(r); r += (global_precision-(prec)); }
|
||||
|
||||
#else /* LOWFIRST byte order */
|
||||
|
||||
/* these definitions assume LSB comes first */
|
||||
#define tohigher(n) (n) /* offset towards higher unit */
|
||||
#define pre_higherunit(r) (++(r))
|
||||
#define pre_lowerunit(r) (--(r))
|
||||
#define post_higherunit(r) ((r)++)
|
||||
#define post_lowerunit(r) ((r)--)
|
||||
#define bit_index(n) (bits2units((n)+1)-1)
|
||||
#define lsbptr(r,prec) (r)
|
||||
#define make_lsbptr(r,prec) /* (r) = lsbptr(r,prec) */
|
||||
#define unmake_lsbptr(r,prec) /* (r) = (r) */
|
||||
#define msbptr(r,prec) ((r)+(prec)-1)
|
||||
#define make_msbptr(r,prec) (r) = msbptr(r,prec)
|
||||
|
||||
#define rescale(r,currentp,newp) /* nil statement */
|
||||
#define normalize(r,prec) prec = significance(r)
|
||||
|
||||
#endif /* LOWFIRST byte order */
|
||||
/*------------------ End byte ordering stuff -------------------*/
|
||||
|
||||
/* Note that the address calculations require that lsbptr, msbptr,
|
||||
make_lsbptr, make_msbptr, mp_tstbit, mp_setbit, mp_clrbit,
|
||||
and bitptr all have unitptr arguments, not byte pointer arguments. */
|
||||
#define bitptr(r,n) &((r)[bit_index(n)])
|
||||
#define bitmsk(n) power_of_2((n) & (UNITSIZE-1))
|
||||
/* bitmsk() assumes UNITSIZE is a power of 2 */
|
||||
#define mp_tstbit(r,n) (*bitptr(r,n) & bitmsk(n))
|
||||
#define mp_setbit(r,n) (*bitptr(r,n) |= bitmsk(n))
|
||||
#define mp_clrbit(r,n) (*bitptr(r,n) &= ~bitmsk(n))
|
||||
#define msunit(r) (*msbptr(r,global_precision))
|
||||
#define lsunit(r) (*lsbptr(r,global_precision))
|
||||
/* #define mp_tstminus(r) ((msunit(r) & uppermostbit)!=0) */
|
||||
#define mp_tstminus(r) ((signedunit) msunit(r) < 0)
|
||||
|
||||
|
||||
/* set working precision to specified number of bits. */
|
||||
#ifdef mp_setp
|
||||
void mp_setp(short nbits);
|
||||
#define set_precision(prec) mp_setp(units2bits(global_precision=(prec)))
|
||||
#else
|
||||
#define set_precision(prec) (global_precision = (prec))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PEASANT
|
||||
|
||||
/* Define C names for Russian peasant modmult primitives. */
|
||||
#define stage_modulus stage_peasant_modulus
|
||||
#define mp_modmult peasant_modmult
|
||||
#define modmult_burn peasant_burn
|
||||
#define SLOP_BITS PEASANT_SLOP_BITS
|
||||
|
||||
#else /* not PEASANT */
|
||||
#ifdef MERRITT
|
||||
/* Define C names for Merritt's modmult primitives. */
|
||||
#define stage_modulus stage_merritt_modulus
|
||||
#define mp_modmult merritt_modmult
|
||||
#define modmult_burn merritt_burn
|
||||
#define SLOP_BITS MERRITT_SLOP_BITS
|
||||
|
||||
#else /* not PEASANT, MERRITT */
|
||||
#ifdef UPTON
|
||||
/* Define C names for Upton's modmult primitives. */
|
||||
#define stage_modulus stage_upton_modulus
|
||||
#define mp_modmult upton_modmult
|
||||
#define modmult_burn upton_burn
|
||||
#define SLOP_BITS UPTON_SLOP_BITS
|
||||
|
||||
#else /* not PEASANT, MERRITT, UPTON */
|
||||
#ifdef SMITH
|
||||
/* Define C names for Smith's modmult primitives. */
|
||||
#define stage_modulus stage_smith_modulus
|
||||
#define mp_modmult smith_modmult
|
||||
#define modmult_burn smith_burn
|
||||
#define SLOP_BITS SMITH_SLOP_BITS
|
||||
|
||||
#endif /* SMITH */
|
||||
#endif /* UPTON */
|
||||
#endif /* MERRITT */
|
||||
#endif /* PEASANT */
|
||||
|
||||
|
||||
#define mp_shift_left(r1) mp_rotate_left(r1,(boolean)0)
|
||||
/* multiprecision shift left 1 bit */
|
||||
|
||||
#define mp_add(r1,r2) mp_addc(r1,r2,(boolean)0)
|
||||
/* multiprecision add with no carry */
|
||||
|
||||
#define mp_sub(r1,r2) mp_subb(r1,r2,(boolean)0)
|
||||
/* multiprecision subtract with no borrow */
|
||||
|
||||
#define mp_abs(r) (mp_tstminus(r) ? (mp_neg(r),TRUE) : FALSE)
|
||||
|
||||
#define msub(r,m) if (mp_compare(r,m) >= 0) mp_sub(r,m)
|
||||
/* Prevents r from getting bigger than modulus m */
|
||||
|
||||
#define testeq(r,i) \
|
||||
( (lsunit(r)==(i)) && (significance(r)<=1) )
|
||||
|
||||
#define testne(r,i) \
|
||||
( (lsunit(r)!=(i)) || (significance(r)>1) )
|
||||
|
||||
#define testge(r,i) \
|
||||
( (lsunit(r)>=(i)) || (significance(r)>1) )
|
||||
|
||||
#define testle(r,i) \
|
||||
( (lsunit(r)<=(i)) && (significance(r)<=1) )
|
||||
|
||||
#define mp_square(r1,r2) mp_mult(r1,r2,r2)
|
||||
/* Square r2, returning product in r1 */
|
||||
|
||||
#define mp_modsquare(r1,r2) mp_modmult(r1,r2,r2)
|
||||
/* Square r2, returning modulo'ed product in r1 */
|
||||
|
||||
#define countbytes(r) ((countbits(r)+7)>>3)
|
||||
|
||||
/* SLOP_BITS is how many "carry bits" to allow for intermediate
|
||||
calculation results to exceed the size of the modulus.
|
||||
It is used by modexp to give some overflow elbow room for
|
||||
modmult to use to perform modulo operations with the modulus.
|
||||
The number of slop bits required is determined by the modmult
|
||||
algorithm. The Russian peasant modmult algorithm only requires
|
||||
1 slop bit, for example. Note that if we use an external assembly
|
||||
modmult routine, SLOP_BITS may be meaningless or may be defined in a
|
||||
non-constant manner.
|
||||
*/
|
||||
#define PEASANT_SLOP_BITS 1
|
||||
#define MERRITT_SLOP_BITS UNITSIZE
|
||||
#define UPTON_SLOP_BITS (UNITSIZE/2)
|
||||
#ifdef mp_smul /* old version requires MS word = 0 */
|
||||
#define SMITH_SLOP_BITS UNITSIZE
|
||||
#else /* mp_smula or C version of mp_smul */
|
||||
#define SMITH_SLOP_BITS 0
|
||||
#endif /* mp_smul */
|
||||
|
||||
/* MAX_BIT_PRECISION is upper limit that assembly primitives can handle.
|
||||
It must be less than 32704 bits, or 4088 bytes. It should be an
|
||||
integer multiple of UNITSIZE*2.
|
||||
*/
|
||||
#if (SLOP_BITS > 0)
|
||||
#define MAX_BIT_PRECISION (1280+(2*UNITSIZE))
|
||||
#else
|
||||
#define MAX_BIT_PRECISION 1280
|
||||
#endif
|
||||
#define MAX_BYTE_PRECISION (MAX_BIT_PRECISION/8)
|
||||
#define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/UNITSIZE)
|
||||
|
||||
|
||||
/* global_precision is the unit precision last set by set_precision */
|
||||
extern short global_precision;
|
||||
|
||||
|
||||
/* The "bit sniffer" macros all begin sniffing at the MSB.
|
||||
They are used internally by all the various multiply, divide,
|
||||
modulo, exponentiation, and square root functions.
|
||||
*/
|
||||
#define sniff_bit(bptr,bitmask) (*(bptr) & bitmask)
|
||||
|
||||
#define init_bitsniffer(bptr,bitmask,prec,bits) \
|
||||
{ normalize(bptr,prec); \
|
||||
if (!prec) \
|
||||
return(0); \
|
||||
bits = units2bits(prec); \
|
||||
make_msbptr(bptr,prec); bitmask = uppermostbit; \
|
||||
while (!sniff_bit(bptr,bitmask)) \
|
||||
{ bitmask >>= 1; bits--; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define bump_bitsniffer(bptr,bitmask) \
|
||||
{ if (!(bitmask >>= 1)) \
|
||||
{ bitmask = uppermostbit; \
|
||||
post_lowerunit(bptr); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* bump_2bitsniffers is used internally by mp_udiv. */
|
||||
#define bump_2bitsniffers(bptr,bptr2,bitmask) \
|
||||
{ if (!(bitmask >>= 1)) \
|
||||
{ bitmask = uppermostbit; \
|
||||
post_lowerunit(bptr); \
|
||||
post_lowerunit(bptr2); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* stuff_bit is used internally by mp_udiv and mp_sqrt. */
|
||||
#define stuff_bit(bptr,bitmask) *(bptr) |= bitmask
|
||||
|
||||
|
||||
boolean mp_addc
|
||||
(register unitptr r1,register unitptr r2,register boolean carry);
|
||||
/* multiprecision add with carry r2 to r1, result in r1 */
|
||||
|
||||
boolean mp_subb
|
||||
(register unitptr r1,register unitptr r2,register boolean borrow);
|
||||
/* multiprecision subtract with borrow, r2 from r1, result in r1 */
|
||||
|
||||
boolean mp_rotate_left(register unitptr r1,register boolean carry);
|
||||
/* multiprecision rotate left 1 bit with carry, result in r1. */
|
||||
|
||||
void mp_shift_right_bits(register unitptr r1,register short bits);
|
||||
/* multiprecision shift right bits, result in r1. */
|
||||
|
||||
short mp_compare(register unitptr r1,register unitptr r2);
|
||||
/* Compares registers *r1, *r2, and returns -1, 0, or 1 */
|
||||
|
||||
boolean mp_inc(register unitptr r);
|
||||
/* Increment multiprecision integer r. */
|
||||
|
||||
boolean mp_dec(register unitptr r);
|
||||
/* Decrement multiprecision integer r. */
|
||||
|
||||
void mp_neg(register unitptr r);
|
||||
/* Compute 2's complement, the arithmetic negative, of r */
|
||||
|
||||
#ifndef mp_move
|
||||
#define mp_move(d,s) memcpy((void*)(d), (void*)(s), \
|
||||
units2bytes(global_precision))
|
||||
#endif
|
||||
#ifndef unitfill0
|
||||
#define unitfill0(r,ct) memset((void*)(r), 0, units2bytes(ct))
|
||||
#endif
|
||||
|
||||
#ifndef mp_burn
|
||||
#define mp_burn(r) mp_init(r,0) /* for burning the evidence */
|
||||
#define mp_init0(r) mp_init(r,0)
|
||||
#endif
|
||||
|
||||
#define empty_array(r) unitfill0(r, sizeof(r)/sizeof(r[0])/sizeof(unit))
|
||||
|
||||
void mp_init(register unitptr r, word16 value);
|
||||
/* Init multiprecision register r with short value. */
|
||||
|
||||
short significance(register unitptr r);
|
||||
/* Returns number of significant units in r */
|
||||
|
||||
int mp_udiv(register unitptr remainder,register unitptr quotient,
|
||||
register unitptr dividend,register unitptr divisor);
|
||||
/* Unsigned divide, treats both operands as positive. */
|
||||
|
||||
int mp_recip(register unitptr quotient,register unitptr divisor);
|
||||
/* Compute reciprocal as 1/divisor. Used by faster modmult. */
|
||||
|
||||
int mp_div(register unitptr remainder,register unitptr quotient,
|
||||
register unitptr dividend,register unitptr divisor);
|
||||
/* Signed divide, either or both operands may be negative. */
|
||||
|
||||
word16 mp_shortdiv(register unitptr quotient,
|
||||
register unitptr dividend,register word16 divisor);
|
||||
/* Returns short remainder of unsigned divide. */
|
||||
|
||||
int mp_mod(register unitptr remainder,
|
||||
register unitptr dividend,register unitptr divisor);
|
||||
/* Unsigned divide, treats both operands as positive. */
|
||||
|
||||
word16 mp_shortmod(register unitptr dividend,register word16 divisor);
|
||||
/* Just returns short remainder of unsigned divide. */
|
||||
|
||||
int mp_mult(register unitptr prod,
|
||||
register unitptr multiplicand,register unitptr multiplier);
|
||||
/* Computes multiprecision prod = multiplicand * multiplier */
|
||||
|
||||
int countbits(unitptr r);
|
||||
/* Returns number of significant bits in r. */
|
||||
|
||||
int stage_peasant_modulus(unitptr n);
|
||||
int stage_merritt_modulus(unitptr n);
|
||||
int stage_upton_modulus(unitptr n);
|
||||
int stage_smith_modulus(unitptr n);
|
||||
/* Must pass modulus to stage_modulus before calling modmult. */
|
||||
|
||||
int peasant_modmult(register unitptr prod,
|
||||
unitptr multiplicand,register unitptr multiplier);
|
||||
int merritt_modmult(register unitptr prod,
|
||||
unitptr multiplicand,register unitptr multiplier);
|
||||
int upton_modmult(register unitptr prod,
|
||||
unitptr multiplicand,register unitptr multiplier);
|
||||
int smith_modmult(register unitptr prod,
|
||||
unitptr multiplicand,register unitptr multiplier);
|
||||
/* Performs combined multiply/modulo operation, with global modulus */
|
||||
|
||||
|
||||
|
||||
int mp_modexp(register unitptr expout,register unitptr expin,
|
||||
register unitptr exponent,register unitptr modulus);
|
||||
/* Combined exponentiation/modulo algorithm. */
|
||||
|
||||
int mp_modexp_crt(unitptr expout, unitptr expin,
|
||||
unitptr p, unitptr q, unitptr ep, unitptr eq, unitptr u);
|
||||
/* exponentiation and modulo using Chinese Remainder Theorem */
|
||||
|
||||
/****************** end of MPI library ****************************/
|
||||
502
lib/ncplib.c
502
lib/ncplib.c
@@ -7,6 +7,12 @@
|
||||
|
||||
#include "ncplib.h"
|
||||
#include "ncplib_err.h"
|
||||
#ifdef SIGNATURES
|
||||
#include "ncpsign.h"
|
||||
#endif
|
||||
#ifdef NDS_SUPPORT
|
||||
#include "ndslib.h"
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
extern pid_t wait(int *);
|
||||
@@ -20,7 +26,7 @@ extern pid_t wait(int *);
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <linux/route.h>
|
||||
#include "kernel/route.h"
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
#include <mntent.h>
|
||||
@@ -28,9 +34,21 @@ extern pid_t wait(int *);
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define NCP_DEFAULT_BUFSIZE 1024
|
||||
#ifdef SIGNATURES
|
||||
#define NCP_DEFAULT_OPTIONS 2
|
||||
int in_options=NCP_DEFAULT_OPTIONS;
|
||||
#endif
|
||||
|
||||
static long
|
||||
ncp_negotiate_buffersize(struct ncp_conn *conn,
|
||||
int size, int *target);
|
||||
#ifdef SIGNATURES
|
||||
static long
|
||||
ncp_negotiate_size_and_options(struct ncp_conn *conn,
|
||||
int size, int options,
|
||||
int *ret_size, int *ret_options);
|
||||
#endif
|
||||
static long
|
||||
ncp_login_object(struct ncp_conn *conn,
|
||||
const unsigned char *username,
|
||||
@@ -93,7 +111,7 @@ ipx_fprint_node(FILE * file, IPXNode node)
|
||||
void
|
||||
ipx_fprint_network(FILE * file, IPXNet net)
|
||||
{
|
||||
fprintf(file, "%08lX", ntohl(net));
|
||||
fprintf(file, "%08X", (u_int32_t)ntohl(net));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -160,15 +178,16 @@ ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target)
|
||||
{
|
||||
char *p;
|
||||
struct sockaddr_ipx addr;
|
||||
unsigned long sipx_network;
|
||||
|
||||
addr.sipx_family = AF_IPX;
|
||||
addr.sipx_type = NCP_PTYPE;
|
||||
|
||||
if (sscanf(buf, "%lx", &addr.sipx_network) != 1)
|
||||
if (sscanf(buf, "%lx", &sipx_network) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
addr.sipx_network = htonl(addr.sipx_network);
|
||||
addr.sipx_network = htonl(sipx_network);
|
||||
if ((p = strchr(buf, ':')) == NULL)
|
||||
{
|
||||
return 1;
|
||||
@@ -341,6 +360,12 @@ do_ncp_call(struct ncp_conn *conn, int request_size)
|
||||
long err;
|
||||
|
||||
memcpy(&request, conn->packet, sizeof(request));
|
||||
#ifdef SIGNATURES
|
||||
if (conn->sign_active)
|
||||
{
|
||||
sign_packet(conn, &request_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (retries > 0)
|
||||
{
|
||||
@@ -394,7 +419,7 @@ do_ncp_call(struct ncp_conn *conn, int request_size)
|
||||
0, 1, &err);
|
||||
goto re_select;
|
||||
}
|
||||
ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE,
|
||||
len = ipx_recv(conn->ncp_sock, conn->packet, NCP_PACKET_SIZE,
|
||||
0, 1, &err);
|
||||
conn->reply_size = len;
|
||||
return 0;
|
||||
@@ -513,6 +538,9 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
|
||||
|
||||
int ncp_sock, wdog_sock;
|
||||
long err;
|
||||
#ifdef SIGNATURES
|
||||
int options;
|
||||
#endif
|
||||
|
||||
conn->is_connected = NOT_CONNECTED;
|
||||
conn->verbose = 0;
|
||||
@@ -582,10 +610,31 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
|
||||
BVAL(conn->packet, 3) + (BVAL(conn->packet, 5) << 8);
|
||||
conn->is_connected = CONN_TEMPORARY;
|
||||
|
||||
if ((ncp_negotiate_buffersize(conn, 1024,
|
||||
&(conn->i.buffer_size)) != 0)
|
||||
#ifdef SIGNATURES
|
||||
conn->sign_wanted = 0;
|
||||
conn->sign_active = 0;
|
||||
|
||||
if ((err = ncp_negotiate_size_and_options(conn,
|
||||
NCP_DEFAULT_BUFSIZE, in_options,
|
||||
&(conn->i.buffer_size), &options)) == 0)
|
||||
{
|
||||
if ((options & 2) != (in_options & 2))
|
||||
{
|
||||
if ((err = ncp_negotiate_size_and_options(conn,
|
||||
NCP_DEFAULT_BUFSIZE, options & 2, &(conn->i.buffer_size),
|
||||
&options)) != 0)
|
||||
options = 0;
|
||||
}
|
||||
if (options & 2)
|
||||
conn->sign_wanted = 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
err = ncp_negotiate_buffersize(conn, NCP_DEFAULT_BUFSIZE,
|
||||
&(conn->i.buffer_size));
|
||||
if ((err != 0)
|
||||
|| (conn->i.buffer_size < 512)
|
||||
|| (conn->i.buffer_size > 1024))
|
||||
|| (conn->i.buffer_size > NCP_DEFAULT_BUFSIZE))
|
||||
{
|
||||
ncp_do_close(conn);
|
||||
return -1;
|
||||
@@ -693,12 +742,33 @@ ncp_open_temporary(struct ncp_conn *conn,
|
||||
|
||||
if (strlen(spec->user) != 0)
|
||||
{
|
||||
#ifdef NDS_SUPPORT
|
||||
if (!nds_get_tree_name(conn, NULL, 0))
|
||||
{
|
||||
if ((err = nds_login_auth(conn, spec->user,
|
||||
spec->password)))
|
||||
{
|
||||
if ((err != NCPL_ET_REQUEST_ERROR) ||
|
||||
(conn->completion != NDS_GRACE_PERIOD))
|
||||
{
|
||||
ncp_do_close(conn);
|
||||
return EACCES;
|
||||
}
|
||||
fprintf(stderr, "Your password has expired\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if (ncp_login_object(conn, spec->user, spec->login_type,
|
||||
spec->password) != 0)
|
||||
{
|
||||
ncp_do_close(conn);
|
||||
return EACCES;
|
||||
}
|
||||
#ifdef NDS_SUPPORT
|
||||
}
|
||||
#endif
|
||||
strcpy(conn->user, spec->user);
|
||||
}
|
||||
return 0;
|
||||
@@ -755,6 +825,16 @@ ncp_find_permanent(const struct ncp_conn_spec *spec)
|
||||
errno = (result == NULL) ? ENOENT : 0;
|
||||
return result;
|
||||
}
|
||||
#ifdef SIGNATURES
|
||||
static void
|
||||
ncp_sign_init_perm(struct ncp_conn *conn)
|
||||
{
|
||||
if (ioctl(conn->mount_fid, NCP_IOC_SIGN_WANTED,
|
||||
&conn->sign_wanted) != 0)
|
||||
conn->sign_wanted = 0;
|
||||
conn->sign_active = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ncp_open_permanent(struct ncp_conn *conn,
|
||||
@@ -792,6 +872,9 @@ ncp_open_permanent(struct ncp_conn *conn,
|
||||
}
|
||||
strcpy(conn->mount_point, mount_point);
|
||||
conn->is_connected = CONN_PERMANENT;
|
||||
#ifdef SIGNATURES
|
||||
ncp_sign_init_perm(conn);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -865,6 +948,9 @@ ncp_open_mount(const char *mount_point, long *err)
|
||||
*err = NCPL_ET_NO_NCPFS_FILE;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef SIGNATURES
|
||||
ncp_sign_init_perm(result);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -937,6 +1023,17 @@ ncp_close(struct ncp_conn *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_mount_uid(int fid, uid_t* uid) {
|
||||
__kernel_uid_t k_uid;
|
||||
int err;
|
||||
|
||||
err = ioctl(fid, NCP_IOC_GETMOUNTUID, &k_uid);
|
||||
if (err) return err;
|
||||
*uid = k_uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ncp_conn_ent *
|
||||
ncp_get_conn_ent(FILE * filep)
|
||||
{
|
||||
@@ -985,7 +1082,7 @@ ncp_get_conn_ent(FILE * filep)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (ioctl(fid, NCP_IOC_GETMOUNTUID, &entry.uid) != 0)
|
||||
if (ncp_get_mount_uid(fid, &entry.uid) != 0)
|
||||
{
|
||||
close(fid);
|
||||
continue;
|
||||
@@ -1568,6 +1665,30 @@ ncp_negotiate_buffersize(struct ncp_conn *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SIGNATURES
|
||||
static long
|
||||
ncp_negotiate_size_and_options(struct ncp_conn *conn,
|
||||
int size, int options,
|
||||
int *ret_size, int *ret_options)
|
||||
{
|
||||
long result;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_word_hl(conn, size);
|
||||
ncp_add_byte(conn, options);
|
||||
|
||||
if ((result = ncp_request(conn, 0x61)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
*ret_size = min(ncp_reply_word_hl(conn, 0), size);
|
||||
*ret_options = ncp_reply_byte(conn, 4);
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
long
|
||||
ncp_get_file_server_description_strings(struct ncp_conn *conn,
|
||||
@@ -1746,6 +1867,34 @@ ncp_send_broadcast(struct ncp_conn *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_send_broadcast2(struct ncp_conn *conn,
|
||||
unsigned int conns, const unsigned int* connlist,
|
||||
const char* message)
|
||||
{
|
||||
int i;
|
||||
long result;
|
||||
|
||||
i = strlen(message);
|
||||
if (i > 255)
|
||||
{
|
||||
return NCPL_ET_MSG_TOO_LONG;
|
||||
}
|
||||
if (conns > 350) /* max pkt len ~ 1KB */
|
||||
/* maybe do it by handshaked length ? */
|
||||
return NCPL_ET_MSG_TOO_LONG;
|
||||
|
||||
ncp_init_request_s(conn, 0x0A);
|
||||
ncp_add_word_lh(conn, conns);
|
||||
for (;conns; --conns)
|
||||
ncp_add_dword_lh(conn, *connlist++);
|
||||
ncp_add_byte(conn, i);
|
||||
ncp_add_mem(conn, message, i);
|
||||
result = ncp_request(conn, 0x15);
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* target is a 8-byte buffer
|
||||
*/
|
||||
@@ -2102,6 +2251,15 @@ ncp_login_encrypted(struct ncp_conn *conn,
|
||||
|
||||
result = ncp_request(conn, 23);
|
||||
ncp_unlock_conn(conn);
|
||||
#ifdef SIGNATURES
|
||||
if ((result == 0) || ((result == NCPL_ET_REQUEST_ERROR) &&
|
||||
(conn->completion == NCP_GRACE_PERIOD)))
|
||||
{
|
||||
memcpy(buf + 16, key, 8);
|
||||
sign_init(buf, buf);
|
||||
result = ncp_sign_start(conn, buf);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3096,6 +3254,143 @@ ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_get_queue_length(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 *queue_length)
|
||||
{
|
||||
long result=-EINVAL;
|
||||
|
||||
ncp_init_request_s(conn, 125);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
goto out;
|
||||
|
||||
if (conn->ncp_reply_size < 12)
|
||||
{
|
||||
ncp_printf("ncp_reply_size %d < 12\n",
|
||||
conn->ncp_reply_size);
|
||||
result=-EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ncp_reply_dword_hl(conn,0) != queue_id)
|
||||
{
|
||||
printf("Ouch! Server didn't reply with same queue id in ncp_get_queue_length!\n");
|
||||
result=-EINVAL;
|
||||
}
|
||||
else
|
||||
*queue_length = ncp_reply_dword_lh(conn,8);
|
||||
|
||||
out:
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_get_queue_job_ids(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 queue_section,
|
||||
__u32 *length1,
|
||||
__u32 *length2,
|
||||
__u32 ids[])
|
||||
{
|
||||
long result;
|
||||
|
||||
ncp_init_request_s(conn,129);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, queue_section);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
goto out;
|
||||
|
||||
if (conn->ncp_reply_size < 8)
|
||||
{
|
||||
ncp_printf("ncp_reply_size %d < 8\n",
|
||||
conn->ncp_reply_size);
|
||||
result=-EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*length2 = ncp_reply_dword_lh(conn,4);
|
||||
if (conn->ncp_reply_size < 8 + 4*(*length2))
|
||||
{
|
||||
ncp_printf("ncp_reply_size %d < %d\n",
|
||||
conn->ncp_reply_size, 8+4*(*length2));
|
||||
result=-EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (ids) {
|
||||
int count = min(*length1, *length2)*sizeof(__u32);
|
||||
int pos;
|
||||
|
||||
for (pos=0; pos<count; pos+=sizeof(__u32)) {
|
||||
*ids++ = ncp_reply_dword_lh(conn, 8+pos);
|
||||
}
|
||||
}
|
||||
*length1 = ncp_reply_dword_lh(conn,0);
|
||||
|
||||
out:
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_get_queue_job_info(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 job_id,
|
||||
struct nw_queue_job_entry *jobdata)
|
||||
{
|
||||
long result;
|
||||
|
||||
ncp_init_request_s(conn,122);
|
||||
ncp_add_dword_hl(conn, queue_id);
|
||||
ncp_add_dword_lh(conn, job_id);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
goto out;
|
||||
|
||||
if (conn->ncp_reply_size < sizeof(struct nw_queue_job_entry))
|
||||
{
|
||||
ncp_printf("ncp_reply_size %d < %d\n",
|
||||
conn->ncp_reply_size,sizeof(struct nw_queue_job_entry));
|
||||
result=-EINVAL;
|
||||
}
|
||||
else
|
||||
memcpy(jobdata,ncp_reply_data(conn,0), sizeof(struct nw_queue_job_entry));
|
||||
|
||||
out:
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
NWRemoveJobFromQueue2
|
||||
(
|
||||
struct ncp_conn* conn,
|
||||
__u32 queueID,
|
||||
__u32 jobNumber
|
||||
) {
|
||||
long result;
|
||||
|
||||
ncp_init_request_s(conn, 0x80);
|
||||
ncp_add_dword_hl(conn, queueID);
|
||||
ncp_add_dword_lh(conn, jobNumber);
|
||||
result = ncp_request(conn, 0x17);
|
||||
if (result) {
|
||||
if (result == NCPL_ET_REQUEST_ERROR) {
|
||||
result = 0x8900 | conn->completion;
|
||||
} else {
|
||||
result = 0x88FF;
|
||||
}
|
||||
} else {
|
||||
/* no output */
|
||||
}
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_do_read(struct ncp_conn *conn, const char *file_id,
|
||||
__u32 offset, __u16 to_read,
|
||||
@@ -3243,12 +3538,16 @@ ncp_get_broadcast_message(struct ncp_conn *conn, char message[256])
|
||||
long result;
|
||||
int length;
|
||||
|
||||
ncp_init_request_s(conn, 1);
|
||||
|
||||
if ((result = ncp_request(conn, 21)) != 0)
|
||||
ncp_init_request_s(conn, 0x0B);
|
||||
if ((result = ncp_request(conn, 0x15)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
ncp_init_request_s(conn, 0x01);
|
||||
if ((result = ncp_request(conn, 0x15)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
length = ncp_reply_byte(conn, 0);
|
||||
message[length] = 0;
|
||||
@@ -3325,3 +3624,180 @@ ncp_add_trustee_set(struct ncp_conn *conn,
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
#ifdef SIGNATURES
|
||||
long
|
||||
ncp_sign_start(struct ncp_conn *conn, const char *sign_root)
|
||||
{
|
||||
char init_last[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
|
||||
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
|
||||
struct ncp_sign_init sign_init;
|
||||
|
||||
if (conn->sign_wanted)
|
||||
{
|
||||
memcpy(sign_init.sign_root, sign_root, 8);
|
||||
memcpy(sign_init.sign_last, init_last, 16);
|
||||
conn->sign_active = 1;
|
||||
if (conn->is_connected == CONN_PERMANENT)
|
||||
{
|
||||
if (ioctl(conn->mount_fid, NCP_IOC_SIGN_INIT,
|
||||
&sign_init))
|
||||
return NCPL_ET_SIGNATURE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(conn->sign_root, sign_init.sign_root, 8);
|
||||
memcpy(conn->sign_last, sign_init.sign_last, 16);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef NDS_SUPPORT
|
||||
long
|
||||
ncp_send_nds_frag(struct ncp_conn *conn,
|
||||
int ndsverb,
|
||||
char *inbuf, int inbuflen,
|
||||
char *outbuf, int outbufsize, int *outbuflen)
|
||||
{
|
||||
long result;
|
||||
int sizeleft, i;
|
||||
int maxdatasize = 514;
|
||||
int first = 1;
|
||||
int fraghnd = -1;
|
||||
|
||||
if (outbuflen) *outbuflen = 0;
|
||||
do
|
||||
{
|
||||
sizeleft = maxdatasize;
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 2);
|
||||
ncp_add_dword_lh(conn, fraghnd);
|
||||
if (first)
|
||||
{
|
||||
ncp_add_dword_lh(conn, maxdatasize - 8);
|
||||
ncp_add_dword_lh(conn, inbuflen + 12);
|
||||
ncp_add_dword_lh(conn, 0);
|
||||
ncp_add_dword_lh(conn, ndsverb);
|
||||
ncp_add_dword_lh(conn, outbufsize);
|
||||
sizeleft -= 25;
|
||||
first = 0;
|
||||
}
|
||||
else
|
||||
sizeleft -= 5;
|
||||
i = (sizeleft > inbuflen) ? inbuflen : sizeleft;
|
||||
if (i) ncp_add_mem(conn, inbuf, i);
|
||||
inbuflen -= i;
|
||||
inbuf += i;
|
||||
if ((result = ncp_request(conn, 0x68)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
if (inbuflen)
|
||||
{
|
||||
if ((ncp_reply_dword_lh(conn, 0) != 4) ||
|
||||
((fraghnd = ncp_reply_dword_lh(conn, 4)) == -1))
|
||||
result = NCPL_ET_REPLY_FORMAT;
|
||||
ncp_unlock_conn(conn);
|
||||
if (result) return result;
|
||||
}
|
||||
} while (inbuflen);
|
||||
i = ncp_reply_dword_lh(conn, 0) - 8;
|
||||
if ((i < 0) || (ncp_reply_dword_lh(conn, 4) != -1))
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return NCPL_ET_REPLY_FORMAT;
|
||||
}
|
||||
if (i > outbufsize)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return NCPL_ET_REPLY_TOO_LARGE;
|
||||
}
|
||||
if (outbuf)
|
||||
{
|
||||
memcpy(outbuf, ncp_reply_data(conn, 12), i);
|
||||
if (outbuflen) *outbuflen = i;
|
||||
}
|
||||
if ((conn->completion = ncp_reply_dword_lh(conn, 8)))
|
||||
result = NCPL_ET_REQUEST_ERROR;
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_send_nds(struct ncp_conn *conn, int fn,
|
||||
char *data_in, int data_in_len,
|
||||
char *data_out, int data_out_max, int *data_out_len)
|
||||
{
|
||||
int i;
|
||||
long err;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, fn);
|
||||
if (data_in) ncp_add_mem(conn, data_in, data_in_len);
|
||||
if (!(err = ncp_request(conn, 0x68)))
|
||||
{
|
||||
i = conn->ncp_reply_size;
|
||||
if (i > data_out_max) i = data_out_max;
|
||||
if (data_out)
|
||||
memcpy(data_out, ncp_reply_data(conn, 0), i);
|
||||
if (data_out_len) *data_out_len = i;
|
||||
}
|
||||
else
|
||||
if (data_out_len) *data_out_len = 0;
|
||||
ncp_unlock_conn(conn);
|
||||
return err;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_change_conn_state(struct ncp_conn *conn, int new_state)
|
||||
{
|
||||
long err;
|
||||
|
||||
ncp_init_request_s(conn, 0x1d);
|
||||
ncp_add_dword_lh(conn, new_state);
|
||||
err = ncp_request(conn, 0x17);
|
||||
ncp_unlock_conn(conn);
|
||||
return err;
|
||||
}
|
||||
|
||||
struct ncp_conn *
|
||||
ncp_open_addr(struct sockaddr_ipx *target, long *err)
|
||||
{
|
||||
struct ncp_conn *conn;
|
||||
FILE *p;
|
||||
char buf[40];
|
||||
|
||||
sprintf(buf, "nwsfind -a %08x:%02x%02x%02x%02x%02x%02x:%04x",
|
||||
(u_int32_t)ntohl(target->sipx_network),
|
||||
(unsigned char)target->sipx_node[0],
|
||||
(unsigned char)target->sipx_node[1],
|
||||
(unsigned char)target->sipx_node[2],
|
||||
(unsigned char)target->sipx_node[3],
|
||||
(unsigned char)target->sipx_node[4],
|
||||
(unsigned char)target->sipx_node[5],
|
||||
ntohs(target->sipx_port));
|
||||
if (!(p = popen(buf, "r"))) {
|
||||
*err = errno;
|
||||
return NULL;
|
||||
}
|
||||
fgets(buf, sizeof(buf), p);
|
||||
if (pclose(p)) {
|
||||
*err = EHOSTUNREACH;
|
||||
return NULL;
|
||||
}
|
||||
if (!(conn = malloc(sizeof(struct ncp_conn))))
|
||||
{
|
||||
*err = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
memzero(*conn);
|
||||
if ((*err = ncp_connect_addr(conn, target, 1)))
|
||||
{
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,4 +42,16 @@ ec NCPL_ET_NO_IPX,
|
||||
ec NCPL_ET_NO_NCPFS_FILE,
|
||||
"The file is probably not on a ncpfs mounted directory"
|
||||
|
||||
end
|
||||
ec NCPL_ET_REPLY_FORMAT,
|
||||
"The reply packet is not in the expected format"
|
||||
|
||||
ec NCPL_ET_REPLY_TOO_LARGE,
|
||||
"The reply packet/message is too large for the allocated buffer"
|
||||
|
||||
ec NCPL_ET_SIGNATURE_FAILED,
|
||||
"Packet signature initializing failed"
|
||||
|
||||
ec NCPL_ET_TRANSPORT_UNKNOWN,
|
||||
"Unknown transport type"
|
||||
|
||||
end
|
||||
|
||||
103
lib/ncpsign.c
Normal file
103
lib/ncpsign.c
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifdef SIGNATURES
|
||||
/*
|
||||
* ncpsign.c
|
||||
*
|
||||
* Arne de Bruijn (arne@knoware.nl), 1997
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ncplib.h"
|
||||
#include "ncpsign.h"
|
||||
|
||||
#define rol32(i,c) (((((i)&0xffffffff)<<c)&0xffffffff)| \
|
||||
(((i)&0xffffffff)>>(32-c)))
|
||||
/* i386: 32-bit, little endian, handles mis-alignment */
|
||||
#ifdef __i386__
|
||||
#define GET_LE32(p) (*(int *)(p))
|
||||
#define PUT_LE32(p,v) { *(int *)(p)=v; }
|
||||
#else
|
||||
#define GET_LE32(p) DVAL_LH(p,0)
|
||||
#define PUT_LE32(p,v) DSET_LH(p,0,v)
|
||||
#endif
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
static void nwsign(char *r_data1, char *r_data2, char *outdata) {
|
||||
int i;
|
||||
unsigned int w0,w1,w2,w3;
|
||||
static int rbit[4]={0, 2, 1, 3};
|
||||
#ifdef __i386__
|
||||
unsigned int *data2=(int *)r_data2;
|
||||
#else
|
||||
unsigned int data2[16];
|
||||
for (i=0;i<16;i++)
|
||||
data2[i]=GET_LE32(r_data2+(i<<2));
|
||||
#endif
|
||||
w0=GET_LE32(r_data1);
|
||||
w1=GET_LE32(r_data1+4);
|
||||
w2=GET_LE32(r_data1+8);
|
||||
w3=GET_LE32(r_data1+12);
|
||||
for (i=0;i<16;i+=4) {
|
||||
w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3);
|
||||
w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7);
|
||||
w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11);
|
||||
w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19);
|
||||
}
|
||||
for (i=0;i<4;i++) {
|
||||
w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3);
|
||||
w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5);
|
||||
w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9);
|
||||
w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13);
|
||||
}
|
||||
for (i=0;i<4;i++) {
|
||||
w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3);
|
||||
w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9);
|
||||
w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11);
|
||||
w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15);
|
||||
}
|
||||
PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff);
|
||||
PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff);
|
||||
PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff);
|
||||
PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize packet signatures
|
||||
* The first 16 bytes of logindata are the shuffled password,
|
||||
* the last 8 bytes the encryption key as received from the server.
|
||||
*/
|
||||
void sign_init(const char *logindata, char *sign_root) {
|
||||
char initlast[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
|
||||
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
|
||||
char *initdata="Authorized NetWare Client";
|
||||
char msg[64];
|
||||
char hash[16];
|
||||
|
||||
memset(msg, 0, 64);
|
||||
memcpy(msg, logindata, 24);
|
||||
memcpy(msg + 24, initdata, 25);
|
||||
nwsign(initlast, msg, hash);
|
||||
|
||||
memcpy(sign_root, hash, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a signature for the current packet and add it at the end of the
|
||||
* packet.
|
||||
*/
|
||||
void sign_packet(struct ncp_conn *conn, int *size) {
|
||||
char data[64];
|
||||
|
||||
memset(data,0,64);
|
||||
memcpy(data,conn->sign_root,8);
|
||||
PUT_LE32(data+8,(*size));
|
||||
memcpy(data+12,conn->packet+sizeof(struct ncp_request_header)-1,
|
||||
min((*size)-sizeof(struct ncp_request_header)+1,52));
|
||||
|
||||
nwsign(conn->sign_last,data,conn->sign_last);
|
||||
|
||||
memcpy(conn->packet+(*size),conn->sign_last,8);
|
||||
(*size)+=8;
|
||||
}
|
||||
#endif
|
||||
295
lib/ndscrypt.c
Normal file
295
lib/ndscrypt.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
NDS client for ncpfs
|
||||
Copyright (C) 1997 Arne de Bruijn
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "ndscrypt.h"
|
||||
|
||||
static unsigned int rol16(unsigned int i, int c) {
|
||||
return ((i << c) & 65535) | ((unsigned int)(i & 65535) >> (16 - c));
|
||||
}
|
||||
static unsigned int ror16(unsigned int i, int c) {
|
||||
return ((unsigned int)(i & 65535) >> c) | ((i << (16 - c)) & 65535);
|
||||
}
|
||||
|
||||
char nwcryptdata[256]={
|
||||
0xD9,0x78,0xF9,0xC4,0x19,0xDD,0xB5,0xED,0x28,0xE9,0xFD,0x79,
|
||||
0x4A,0xA0,0xD8,0x9D,0xC6,0x7E,0x37,0x83,0x2B,0x76,0x53,0x8E,
|
||||
0x62,0x4C,0x64,0x88,0x44,0x8B,0xFB,0xA2,0x17,0x9A,0x59,0xF5,
|
||||
0x87,0xB3,0x4F,0x13,0x61,0x45,0x6D,0x8D,0x09,0x81,0x7D,0x32,
|
||||
0xBD,0x8F,0x40,0xEB,0x86,0xB7,0x7B,0x0B,0xF0,0x95,0x21,0x22,
|
||||
0x5C,0x6B,0x4E,0x82,0x54,0xD6,0x65,0x93,0xCE,0x60,0xB2,0x1C,
|
||||
0x73,0x56,0xC0,0x14,0xA7,0x8C,0xF1,0xDC,0x12,0x75,0xCA,0x1F,
|
||||
0x3B,0xBE,0xE4,0xD1,0x42,0x3D,0xD4,0x30,0xA3,0x3C,0xB6,0x26,
|
||||
0x6F,0xBF,0x0E,0xDA,0x46,0x69,0x07,0x57,0x27,0xF2,0x1D,0x9B,
|
||||
0xBC,0x94,0x43,0x03,0xF8,0x11,0xC7,0xF6,0x90,0xEF,0x3E,0xE7,
|
||||
0x06,0xC3,0xD5,0x2F,0xC8,0x66,0x1E,0xD7,0x08,0xE8,0xEA,0xDE,
|
||||
0x80,0x52,0xEE,0xF7,0x84,0xAA,0x72,0xAC,0x35,0x4D,0x6A,0x2A,
|
||||
0x96,0x1A,0xD2,0x71,0x5A,0x15,0x49,0x74,0x4B,0x9F,0xD0,0x5E,
|
||||
0x04,0x18,0xA4,0xEC,0xC2,0xE0,0x41,0x6E,0x0F,0x51,0xCB,0xCC,
|
||||
0x24,0x91,0xAF,0x50,0xA1,0xF4,0x70,0x39,0x99,0x7C,0x3A,0x85,
|
||||
0x23,0xB8,0xB4,0x7A,0xFC,0x02,0x36,0x5B,0x25,0x55,0x97,0x31,
|
||||
0x2D,0x5D,0xFA,0x98,0xE3,0x8A,0x92,0xAE,0x05,0xDF,0x29,0x10,
|
||||
0x67,0x6C,0xBA,0xC9,0xD3,0x00,0xE6,0xCF,0xE1,0x9E,0xA8,0x2C,
|
||||
0x63,0x16,0x01,0x3F,0x58,0xE2,0x89,0xA9,0x0D,0x38,0x34,0x1B,
|
||||
0xAB,0x33,0xFF,0xB0,0xBB,0x48,0x0C,0x5F,0xB9,0xB1,0xCD,0x2E,
|
||||
0xC5,0xF3,0xDB,0x47,0xE5,0xA5,0x9C,0x77,0x0A,0xA6,0x20,0x68,
|
||||
0xFE,0x7F,0xC1,0xAD};
|
||||
|
||||
#if 0
|
||||
char shuffle_table[32]=
|
||||
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
|
||||
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
|
||||
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
||||
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
||||
|
||||
char shuffle_table2[256] =
|
||||
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
|
||||
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
|
||||
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
|
||||
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
|
||||
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
|
||||
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
|
||||
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
|
||||
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
|
||||
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
|
||||
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
|
||||
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
|
||||
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
|
||||
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
|
||||
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
|
||||
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
|
||||
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
|
||||
#endif
|
||||
|
||||
char nwhashdata[256] =
|
||||
{0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,
|
||||
0x1B,0x33,0xFD,0xD0,0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,
|
||||
0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,0x41,0x9F,0xE1,0xD9,
|
||||
0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,
|
||||
0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,
|
||||
0xA6,0x3F,0xD8,0x0C,0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,
|
||||
0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,0x48,0xE6,0x1E,0x53,
|
||||
0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,
|
||||
0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,
|
||||
0xBA,0x3C,0x06,0x4E,0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,
|
||||
0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,0x3A,0xDE,0x96,0x0E,
|
||||
0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,
|
||||
0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,
|
||||
0x75,0xD5,0x61,0xE3,0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,
|
||||
0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,0xB4,0xC5,0xCC,0x70,
|
||||
0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,
|
||||
0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,
|
||||
0x82,0xF9,0x40,0xB5,0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,
|
||||
0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,0x64,0x6D,0x7A,0xD4,
|
||||
0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,
|
||||
0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,
|
||||
0x4C,0xFF,0x43,0xAB};
|
||||
|
||||
|
||||
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out) {
|
||||
int i, j;
|
||||
register unsigned int i1, i2, i3, i4;
|
||||
unsigned short *p;
|
||||
|
||||
i1 = *((unsigned short *)in);
|
||||
i2 = *((unsigned short *)in + 1);
|
||||
i3 = *((unsigned short *)in + 2);
|
||||
i4 = *((unsigned short *)in + 3);
|
||||
p = (unsigned short *)cryptbuf;
|
||||
for (j = 3; j; j--) {
|
||||
for (i = (j == 2) ? 6 : 5; i; i--) {
|
||||
i1 = rol16(i1 + (*p++) + (i4 & i3) + (~i4 & i2), 1);
|
||||
i2 = rol16(i2 + (*p++) + (i1 & i4) + (~i1 & i3), 2);
|
||||
i3 = rol16(i3 + (*p++) + (i2 & i1) + (~i2 & i4), 3);
|
||||
i4 = rol16(i4 + (*p++) + (i3 & i2) + (~i3 & i1), 5);
|
||||
}
|
||||
if (j > 1) {
|
||||
i1 += cryptbuf[i4 & 63];
|
||||
i2 += cryptbuf[i1 & 63];
|
||||
i3 += cryptbuf[i2 & 63];
|
||||
i4 += cryptbuf[i3 & 63];
|
||||
}
|
||||
}
|
||||
*((unsigned short *)out) = i1;
|
||||
*((unsigned short *)out + 1) = i2;
|
||||
*((unsigned short *)out + 2) = i3;
|
||||
*((unsigned short *)out + 3) = i4;
|
||||
}
|
||||
|
||||
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out) {
|
||||
int i, j;
|
||||
unsigned short *p;
|
||||
register unsigned int i1, i2, i3, i4;
|
||||
|
||||
i1 = *((unsigned short *)in);
|
||||
i2 = *((unsigned short *)in + 1);
|
||||
i3 = *((unsigned short *)in + 2);
|
||||
i4 = *((unsigned short *)in + 3);
|
||||
p = (unsigned short *)cryptbuf + 64;
|
||||
for (j = 3; j; j--) {
|
||||
for (i = (j == 2) ? 6 : 5; i; i--) {
|
||||
i4 = ror16(i4, 5) - (~i3 & i1) - (i3 & i2) - (*--p);
|
||||
i3 = ror16(i3, 3) - (~i2 & i4) - (i2 & i1) - (*--p);
|
||||
i2 = ror16(i2, 2) - (~i1 & i3) - (i1 & i4) - (*--p);
|
||||
i1 = ror16(i1, 1) - (~i4 & i2) - (i4 & i3) - (*--p);
|
||||
}
|
||||
if (j > 1) {
|
||||
i4 -= cryptbuf[i3 & 63];
|
||||
i3 -= cryptbuf[i2 & 63];
|
||||
i2 -= cryptbuf[i1 & 63];
|
||||
i1 -= cryptbuf[i4 & 63];
|
||||
}
|
||||
}
|
||||
*((unsigned short *)out) = i1;
|
||||
*((unsigned short *)out + 1) = i2;
|
||||
*((unsigned short *)out + 2) = i3;
|
||||
*((unsigned short *)out + 3) = i4;
|
||||
}
|
||||
|
||||
void nwcryptinit(unsigned short *scryptbuf, const char *key) {
|
||||
int i;
|
||||
unsigned char cryptbuf[128], *p;
|
||||
|
||||
memcpy(cryptbuf, key, 8);
|
||||
for (i = 0; i < 120; i++)
|
||||
cryptbuf[i + 8] =
|
||||
nwcryptdata[(unsigned char)(cryptbuf[i] + cryptbuf[i + 7]) & 255];
|
||||
cryptbuf[128 - 8] = nwcryptdata[(unsigned char)cryptbuf[128 - 8] & 255];
|
||||
for (i = 127 - 8; i >= 0; i--)
|
||||
cryptbuf[i] = nwcryptdata[(unsigned char)cryptbuf[i + 1] ^
|
||||
(unsigned char)cryptbuf[i + 8]];
|
||||
for (i = 0, p = cryptbuf; i < 64; i++, p += 2)
|
||||
scryptbuf[i] = (*p) | (*(p+1)) << 8;
|
||||
}
|
||||
|
||||
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
|
||||
char *outbuf) {
|
||||
int i;
|
||||
char nhash[8];
|
||||
unsigned short cryptbuf[64];
|
||||
|
||||
nwcryptinit(cryptbuf, cryptkey);
|
||||
memset(nhash, 0, 8);
|
||||
while (buflen >= 8) {
|
||||
for (i = 0; i < 8; i++, buf++)
|
||||
nhash[i] ^= *buf;
|
||||
nwencrypt(cryptbuf, nhash, nhash);
|
||||
memcpy(outbuf, nhash, 8);
|
||||
outbuf += 8;
|
||||
buflen -= 8;
|
||||
}
|
||||
memset(cryptbuf, 0, sizeof(cryptbuf));
|
||||
}
|
||||
|
||||
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
|
||||
char *outbuf) {
|
||||
int i;
|
||||
char nhash[16], *p;
|
||||
unsigned short cryptbuf[64];
|
||||
|
||||
nwcryptinit(cryptbuf, cryptkey);
|
||||
memset(nhash, 0, 16);
|
||||
p = nhash;
|
||||
while (buflen >= 8) {
|
||||
memcpy(p, buf, 8);
|
||||
p = nhash + 8 - (p - nhash);
|
||||
nwdecrypt(cryptbuf, buf, outbuf);
|
||||
for (i = 0; i < 8; i++, outbuf++)
|
||||
*outbuf ^= p[i];
|
||||
buf += 8;
|
||||
buflen -= 8;
|
||||
}
|
||||
memset(cryptbuf, 0, sizeof(cryptbuf));
|
||||
}
|
||||
|
||||
void nwhash1(char *hash, int hashlen, const char *data, int datalen) {
|
||||
unsigned char *hp, *hp1, *dp, *hend, c;
|
||||
|
||||
hp1 = (hp = (unsigned char *)hash) + 1;
|
||||
hend = hp + hashlen;
|
||||
dp = (unsigned char *)data;
|
||||
while (datalen--) {
|
||||
*hp = nwhashdata[*hp1 ^ *hp] ^ *dp++;
|
||||
hp = hp1++;
|
||||
if (hp1 == hend)
|
||||
hp1 = (unsigned char *)hash;
|
||||
}
|
||||
while (hp-- > (unsigned char *)hash) {
|
||||
hp1 = (unsigned char *)hash;
|
||||
c = *hp1++;
|
||||
while (*(hp1 - 1) = *hp1, ++hp1 < (unsigned char *)hash + hashlen);
|
||||
*(hp1 - 1) = c;
|
||||
}
|
||||
}
|
||||
|
||||
void nwhash2(char *hashbuf, char c) {
|
||||
int i, j;
|
||||
char *p = hashbuf + hashbuf[0x40];
|
||||
|
||||
p[0x20] = p[0x00] ^ (p[0x10] = c);
|
||||
hashbuf[0x41] = (p[0x30] ^= nwhashdata[(unsigned char)(c ^ hashbuf[0x41])]);
|
||||
if (!(hashbuf[0x40] = (hashbuf[0x40] + 1) & 15)) {
|
||||
c = 0;
|
||||
for (i = 18; i; i--)
|
||||
for (j = 48, p = hashbuf; j; j--)
|
||||
c = (*(p++) ^= nwhashdata[((unsigned char)c + j) & 255]);
|
||||
}
|
||||
}
|
||||
|
||||
void nwhash2block(char *hashbuf, const char *data, int datalen) {
|
||||
while (datalen--)
|
||||
nwhash2(hashbuf, *data++);
|
||||
}
|
||||
|
||||
void nwhash2end(char *hashbuf) {
|
||||
int i, j;
|
||||
|
||||
for(j = i = 16 - hashbuf[0x40]; j; j--)
|
||||
nwhash2(hashbuf, i);
|
||||
for(i = 0x30; i < 0x40; i++)
|
||||
nwhash2(hashbuf, hashbuf[i]);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void shuffle(const char *objid, const char *pwd, char *out) {
|
||||
unsigned char temp[32];
|
||||
int i, j, k;
|
||||
i = strlen(pwd);
|
||||
memset(temp, 0, 32);
|
||||
for (j = 0; j < i; j++)
|
||||
temp[j & 31] ^= pwd[j];
|
||||
if (i)
|
||||
for (j = i; j < 32; j += i) {
|
||||
temp[j++] = shuffle_table[j];
|
||||
k = 32 - j;
|
||||
memcpy(temp + j, pwd, (k > i) ? i : k);
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
temp[i] ^= objid[i & 3];
|
||||
j = 0;
|
||||
for (k = 0; k < 2; k++)
|
||||
for (i = 0; i < 32; i++)
|
||||
(char)j += temp[i] = (temp[i] + j) ^
|
||||
(temp[(i + j) & 31] - shuffle_table[i]);
|
||||
for (i = 0; i < 16; i++)
|
||||
out[i] = shuffle_table2[temp[i * 2]] |
|
||||
(shuffle_table2[temp[i * 2 + 1]] << 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
47
lib/ndscrypt.h
Normal file
47
lib/ndscrypt.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
NDS client for ncpfs
|
||||
Copyright (C) 1997 Arne de Bruijn
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _NDSCRYPT_H
|
||||
#define _NDSCRYPT_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void nwencrypt(const unsigned short *cryptbuf, const char *in, char *out);
|
||||
void nwdecrypt(const unsigned short *cryptbuf, const char *in, char *out);
|
||||
void nwcryptinit(unsigned short *scryptbuf, const char *key);
|
||||
void nwencryptblock(const char *cryptkey, const char *buf, int buflen,
|
||||
char *outbuf);
|
||||
void nwdecryptblock(const char *cryptkey, const char *buf, int buflen,
|
||||
char *outbuf);
|
||||
|
||||
#define nwhash1init(hash, hashlen) memset(hash, 0, hashlen)
|
||||
void nwhash1(char *hash, int hashlen, const char *data, int datalen);
|
||||
|
||||
#define nwhash2init(hashbuf) memset(hashbuf, 0, 0x42)
|
||||
void nwhash2(char *hashbuf, char c);
|
||||
void nwhash2block(char *hashbuf, const char *data, int datalen);
|
||||
void nwhash2end(char *hashbuf);
|
||||
|
||||
#if 0
|
||||
void shuffle(const char *objid, const char *pwd, char *out);
|
||||
#else
|
||||
void shuffle(const char *objid, const char *pwd, int buflen, char *out);
|
||||
#endif
|
||||
|
||||
#endif /* _NDSCRYPT_H */
|
||||
1235
lib/ndslib.c
Normal file
1235
lib/ndslib.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -142,7 +142,7 @@ shuffle1(buf32 temp, unsigned char *target)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
|
||||
unsigned char *target)
|
||||
{
|
||||
|
||||
218
lib/platform.h
Normal file
218
lib/platform.h
Normal file
@@ -0,0 +1,218 @@
|
||||
/* platform.h - computer platform customization for PGP
|
||||
multiprecision math package. #Included in mpilib.h.
|
||||
*/
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
/* Platform customization:
|
||||
* A version which runs on almost any computer can be implemented by
|
||||
* defining PORTABLE and MPORTABLE, preferably as a command line
|
||||
* parameter. Faster versions can be generated by specifying specific
|
||||
* parameters, such as size of unit and MULTUNIT, and by supplying some
|
||||
* of the critical in assembly.
|
||||
*
|
||||
* This file holds customizations for different environments.
|
||||
* This is done in one of two ways:
|
||||
* 1. A symbol is defined on the command line which designates a
|
||||
* particular environment, such as MSDOS. This file detects the
|
||||
* environment symbol and sets the appropriate low-level defines.
|
||||
*
|
||||
* 2. If no environment is named, the low-level defines are set in
|
||||
* the same manner as for PGP 2.0, thereby providing an easy upgrade.
|
||||
*
|
||||
* Following are a description of the low-level definition symbols:
|
||||
*
|
||||
* The following preprocessor symbols should be conditionally set to
|
||||
* optimize for a particular environment.
|
||||
*
|
||||
* Define one of the following:
|
||||
* UNIT8, UNIT16, or UNIT32 - specifies size of operands for
|
||||
* multiprecision add, subtract, shift, and initialization operations.
|
||||
* Define one of the following:
|
||||
* MUNIT8, MUNIT16, MUNIT32 - specified size of operands for
|
||||
* multiprecision multiply and mod_mult. This must be less than or
|
||||
* equal to unit size. It should be the word size for the native
|
||||
* atomic multiply instruction. For a 16x16 bit multiply yielding a
|
||||
* 32-bit product, MUNIT16 should be set.
|
||||
* Define one (or more) of the following:
|
||||
* PEASANT, MERRITT, UPTON, SMITH -algorithm used for modmult. All defined
|
||||
* algorithms are compiled, but the first defined name listed will be
|
||||
* assigned to the generic entry point symbols. Multiple algorithms are
|
||||
* used primarily for testing.
|
||||
* HIGHFIRST - specified if longs are stored with the most significant
|
||||
* bit at the lowest address (Motorola), undefined otherwise. This should
|
||||
* be defined on the command line, normally in the makefile.
|
||||
*
|
||||
* The following symbol, if initialized, is set to specific values:
|
||||
* ALIGN - variable declaration attribute which forces optimum alignment
|
||||
* of words, e.g. for VAX C: ALIGN=_align(quadword)
|
||||
*
|
||||
* The following symbols correspond to individual multiprecision routines
|
||||
* that may be implemented with assembly language. If they are implemented
|
||||
* in assembly, the symbols should be defined with the name of the
|
||||
* corresponding external entry points, e.g., mp_addc=P_ADDC
|
||||
* mp_setp - set precision for external routines
|
||||
* mp_addc - add with carry
|
||||
* mp_subb - subtract with borrow
|
||||
* mp_rotate_left - rotate left
|
||||
* mp_compare - compare
|
||||
* mp_move - move
|
||||
* unitfill0 - zero fill
|
||||
* mp_smul - multiply vector by single word *
|
||||
* mp_smula - multiply vector by single word and accumulate *
|
||||
* mp_dmul - full multiply
|
||||
* mp_set_recip - setup for mp_quo_digit
|
||||
* mp_quo_digit - quotient digit for modulus reduction
|
||||
*
|
||||
* Either mp_smul or mp_smula should be defined. mp_smula provides
|
||||
* for accumulation to an existing value, while mp_smul is for use of the
|
||||
* older definition of mp_smul, used in PGP 2.0, which assumed that the high
|
||||
* order accumulator word is zero. Use of mp_smula causes one less word of
|
||||
* precision to be used, thereby slightly increasing speed.
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* Environment customization. Please send any additions or corrections
|
||||
* to Philip Zimmermann.
|
||||
*/
|
||||
#ifndef PORTABLE
|
||||
|
||||
#ifdef MSDOS
|
||||
#ifndef i386 /* gcc */
|
||||
#define UNIT16
|
||||
#define MUNIT16
|
||||
#define mp_setp P_SETP
|
||||
#define mp_addc P_ADDC
|
||||
#define mp_subb P_SUBB
|
||||
#define mp_rotate_left P_ROTL
|
||||
#define mp_smula P_SMULA
|
||||
#define mp_quo_digit P_QUO_DIGIT
|
||||
#define mp_set_recip P_SETRECIP
|
||||
#define SMITH
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* i386 */
|
||||
#endif /* MSDOS */
|
||||
|
||||
#ifdef VMS
|
||||
#define UNIT32 /* use 32-bit units */
|
||||
#define MUNIT32 /* not used in C code, only in assembler */
|
||||
#define UPTON
|
||||
#define mp_setp p_setp
|
||||
#define mp_addc p_addc
|
||||
#define mp_subb p_subb
|
||||
#define mp_rotate_left p_rotl
|
||||
#define mp_smul p_smul
|
||||
#define mp_dmul p_dmul
|
||||
#define mp_compare p_cmp
|
||||
#define ALIGN _align(quadword)
|
||||
|
||||
#ifdef VAXC
|
||||
/*
|
||||
* A VAX is a CISC machine. Unfortunately C is at to low a level to use
|
||||
* many of the instruction set enhancements so we define some macros
|
||||
* here that implement fast moves and fast zero fills with single
|
||||
* instructions.
|
||||
*/
|
||||
#pragma builtins
|
||||
#define mp_move( dst, src) _MOVC3( global_precision*4, (char *) src, (char *) dst)
|
||||
#define unitfill0( r, unitcount) _MOVC5( 0, (char *) 0, 0, unitcount*4, (char *) r)
|
||||
#define mp_burn(r) _MOVC5(0, (char *) 0, 0, global_precision*4, (char *) r)
|
||||
#define mp_init0(r) mp_burn(r) /* Just for documentation purposes */
|
||||
#endif /* VAXC */
|
||||
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* VMS */
|
||||
|
||||
#ifdef mips
|
||||
/*
|
||||
* Needs r3kd.s and r3000.s (or r3000.c)
|
||||
*/
|
||||
#define UNIT32
|
||||
#define MUNIT32
|
||||
#define SMITH
|
||||
#define mp_dmul p_dmul
|
||||
#define mp_setp p_setp
|
||||
#define mp_addc p_addc
|
||||
#define mp_subb p_subb
|
||||
#define mp_rotate_left p_rotl
|
||||
#define mp_smula p_smula
|
||||
#define mp_quo_digit p_quo_digit
|
||||
#define mp_set_recip p_setrecip
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* mips */
|
||||
|
||||
#ifdef i386
|
||||
/*
|
||||
* Needs 80386.S
|
||||
*/
|
||||
#define UNIT32
|
||||
#define MUNIT32
|
||||
#define SMITH
|
||||
#define mp_setp P_SETP
|
||||
#define mp_addc P_ADDC
|
||||
#define mp_subb P_SUBB
|
||||
#define mp_rotate_left P_ROTL
|
||||
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
|
||||
#define mp_smula P_SMULA
|
||||
#define mp_quo_digit p_quo_digit
|
||||
#define mp_set_recip p_setrecip
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* i386 */
|
||||
|
||||
#ifdef sparc
|
||||
/*
|
||||
* Needs sparc.s
|
||||
*/
|
||||
#define UNIT32
|
||||
#define MERRITT
|
||||
#define mp_setp P_SETP
|
||||
#define mp_addc P_ADDC
|
||||
#define mp_subb P_SUBB
|
||||
#define mp_rotate_left P_ROTL
|
||||
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* sparc */
|
||||
|
||||
#if defined(mc68000) || defined(mc68020)
|
||||
/*
|
||||
* Needs mc68020.S
|
||||
*/
|
||||
#define UNIT32
|
||||
#define mp_setp P_SETP
|
||||
#define mp_addc P_ADDC
|
||||
#define mp_subb P_SUBB
|
||||
#define mp_rotate_left P_ROTL
|
||||
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
|
||||
#if defined(sun3) || defined(mc68020)
|
||||
# define UPTON
|
||||
# define MUNIT32
|
||||
# define mp_smul P_SMUL
|
||||
/* # define mp_dmul P_DMUL */ /* mc68020.s has a bug in P_DMUL */
|
||||
#else
|
||||
# define SMITH
|
||||
# define MUNIT16
|
||||
#endif
|
||||
#define PLATFORM_SPECIFIED
|
||||
#endif /* mc68000 */
|
||||
|
||||
/* Add additional platforms here ... */
|
||||
|
||||
/**************** End of system specification ************************/
|
||||
|
||||
#ifndef PLATFORM_SPECIFIED
|
||||
/* No platform explicitly selected. Customization is controlled by
|
||||
* PORTABLE and MPORTABLE.
|
||||
*/
|
||||
#define mp_setp P_SETP
|
||||
#define mp_addc P_ADDC
|
||||
#define mp_subb P_SUBB
|
||||
#define mp_rotate_left P_ROTL
|
||||
#define UPTON
|
||||
#define unitfill0(r,ct) memset((void*)r, 0, (ct)*sizeof(unit))
|
||||
#ifndef MPORTABLE
|
||||
#define mp_smul P_SMUL
|
||||
#endif /* MPORTABLE */
|
||||
#endif /* PLATFORM_SPECIFIED */
|
||||
#endif /* PORTABLE */
|
||||
#endif /* PLATFORM_H */
|
||||
|
||||
41
lib/usuals.h
Normal file
41
lib/usuals.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* usuals.h - The usual typedefs, etc.
|
||||
*/
|
||||
#ifndef USUALS /* Assures no redefinitions of usual types...*/
|
||||
#define USUALS
|
||||
|
||||
typedef unsigned char boolean; /* values are TRUE or FALSE */
|
||||
typedef unsigned char byte; /* values are 0-255 */
|
||||
typedef byte *byteptr; /* pointer to byte */
|
||||
typedef char *string; /* pointer to ASCII character string */
|
||||
typedef unsigned short word16; /* values are 0-65535 */
|
||||
#ifdef __alpha
|
||||
typedef unsigned int word32; /* values are 0-4294967295 */
|
||||
#else
|
||||
typedef unsigned long word32; /* values are 0-4294967295 */
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
#endif /* if TRUE not already defined */
|
||||
|
||||
#ifndef min /* if min macro not already defined */
|
||||
#define min(a,b) (((a)<(b)) ? (a) : (b) )
|
||||
#define max(a,b) (((a)>(b)) ? (a) : (b) )
|
||||
#endif /* if min macro not already defined */
|
||||
|
||||
/* void for use in pointers */
|
||||
#ifndef NO_VOID_STAR
|
||||
#define VOID void
|
||||
#else
|
||||
#define VOID char
|
||||
#endif
|
||||
|
||||
/* Zero-fill the byte buffer. */
|
||||
#define fill0(buffer,count) memset( buffer, 0, count )
|
||||
|
||||
/* This macro is for burning sensitive data. Many of the
|
||||
file I/O routines use it for zapping buffers */
|
||||
#define burn(x) fill0((VOID *)&(x),sizeof(x))
|
||||
|
||||
#endif /* if USUALS not already defined */
|
||||
Reference in New Issue
Block a user