xref: /onnv-gate/usr/src/uts/common/gssapi/mechs/krb5/crypto/nfold.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
2*7934SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * Copyright (C) 1998 by the FundsXpress, INC.
9*7934SMark.Phalan@Sun.COM  *
100Sstevel@tonic-gate  * All rights reserved.
11*7934SMark.Phalan@Sun.COM  *
120Sstevel@tonic-gate  * Export of this software from the United States of America may require
130Sstevel@tonic-gate  * a specific license from the United States Government.  It is the
140Sstevel@tonic-gate  * responsibility of any person or organization contemplating export to
150Sstevel@tonic-gate  * obtain such a license before exporting.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
180Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
190Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
200Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
210Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
220Sstevel@tonic-gate  * the name of FundsXpress. not be used in advertising or publicity pertaining
230Sstevel@tonic-gate  * to distribution of the software without specific, written prior
240Sstevel@tonic-gate  * permission.  FundsXpress makes no representations about the suitability of
250Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
260Sstevel@tonic-gate  * or implied warranty.
270Sstevel@tonic-gate  *
280Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
290Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
300Sstevel@tonic-gate  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
33*7934SMark.Phalan@Sun.COM #include "k5-int.h"
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * Solaris Kerberos defines memory management macros in <krb5.h>,
370Sstevel@tonic-gate  * which is included by <k5-int.h>, so we need not include <memory.h>
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate /* #include <memory.h> */
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate n-fold(k-bits):
430Sstevel@tonic-gate   l = lcm(n,k)
440Sstevel@tonic-gate   r = l/k
450Sstevel@tonic-gate   s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1)
460Sstevel@tonic-gate   compute the 1's complement sum:
470Sstevel@tonic-gate 	n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1]
480Sstevel@tonic-gate */
490Sstevel@tonic-gate 
500Sstevel@tonic-gate /* representation: msb first, assume n and k are multiples of 8, and
510Sstevel@tonic-gate    that k>=16.  this is the case of all the cryptosystems which are
520Sstevel@tonic-gate    likely to be used.  this function can be replaced if that
530Sstevel@tonic-gate    assumption ever fails.  */
540Sstevel@tonic-gate 
550Sstevel@tonic-gate /* input length is in bits */
560Sstevel@tonic-gate 
570Sstevel@tonic-gate void
krb5_nfold(unsigned int inbits,const unsigned char * in,unsigned int outbits,unsigned char * out)58*7934SMark.Phalan@Sun.COM krb5_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits,
59*7934SMark.Phalan@Sun.COM 	   unsigned char *out)
600Sstevel@tonic-gate {
610Sstevel@tonic-gate     int a,b,c,lcm;
620Sstevel@tonic-gate     int byte, i, msbit;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate     /* the code below is more readable if I make these bytes
650Sstevel@tonic-gate        instead of bits */
660Sstevel@tonic-gate 
670Sstevel@tonic-gate     inbits >>= 3;
680Sstevel@tonic-gate     outbits >>= 3;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate     /* first compute lcm(n,k) */
710Sstevel@tonic-gate 
720Sstevel@tonic-gate     a = outbits;
730Sstevel@tonic-gate     b = inbits;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate     while(b != 0) {
760Sstevel@tonic-gate 	c = b;
770Sstevel@tonic-gate 	b = a%b;
780Sstevel@tonic-gate 	a = c;
790Sstevel@tonic-gate     }
800Sstevel@tonic-gate 
810Sstevel@tonic-gate     lcm = outbits*inbits/a;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate     /* now do the real work */
840Sstevel@tonic-gate 
850Sstevel@tonic-gate     (void) memset(out, 0, outbits);
860Sstevel@tonic-gate     byte = 0;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate     /* this will end up cycling through k lcm(k,n)/k times, which
890Sstevel@tonic-gate        is correct */
900Sstevel@tonic-gate     for (i=lcm-1; i>=0; i--) {
910Sstevel@tonic-gate 	/* compute the msbit in k which gets added into this byte */
920Sstevel@tonic-gate 	msbit = (/* first, start with the msbit in the first, unrotated
930Sstevel@tonic-gate 		    byte */
940Sstevel@tonic-gate 		 ((inbits<<3)-1)
950Sstevel@tonic-gate 		 /* then, for each byte, shift to the right for each
960Sstevel@tonic-gate 		    repetition */
970Sstevel@tonic-gate 		 +(((inbits<<3)+13)*(i/inbits))
980Sstevel@tonic-gate 		 /* last, pick out the correct byte within that
990Sstevel@tonic-gate 		    shifted repetition */
1000Sstevel@tonic-gate 		 +((inbits-(i%inbits))<<3)
1010Sstevel@tonic-gate 		 )%(inbits<<3);
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	/* pull out the byte value itself */
1040Sstevel@tonic-gate 	byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)|
1050Sstevel@tonic-gate 		  (in[((inbits)-(msbit>>3))%inbits]))
1060Sstevel@tonic-gate 		 >>((msbit&7)+1))&0xff;
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate 	/* do the addition */
1090Sstevel@tonic-gate 	byte += out[i%outbits];
1100Sstevel@tonic-gate 	out[i%outbits] = byte&0xff;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate #if 0
1130Sstevel@tonic-gate 	printf("msbit[%d] = %d\tbyte = %02x\tsum = %03x\n", i, msbit,
1140Sstevel@tonic-gate 	       (((in[((inbits-1)-(msbit>>3))%inbits]<<8)|
1150Sstevel@tonic-gate 		 (in[((inbits)-(msbit>>3))%inbits]))
1160Sstevel@tonic-gate 		>>((msbit&7)+1))&0xff, byte);
1170Sstevel@tonic-gate #endif
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	/* keep around the carry bit, if any */
1200Sstevel@tonic-gate 	byte >>= 8;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate #if 0
1230Sstevel@tonic-gate 	printf("carry=%d\n", byte);
1240Sstevel@tonic-gate #endif
1250Sstevel@tonic-gate     }
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate     /* if there's a carry bit left over, add it back in */
1280Sstevel@tonic-gate     if (byte) {
1290Sstevel@tonic-gate 	for (i=outbits-1; i>=0; i--) {
1300Sstevel@tonic-gate 	    /* do the addition */
1310Sstevel@tonic-gate 	    byte += out[i];
1320Sstevel@tonic-gate 	    out[i] = byte&0xff;
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	    /* keep around the carry bit, if any */
1350Sstevel@tonic-gate 	    byte >>= 8;
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate     }
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate 
140