1*50a9bdd4SDavid du Colombier /* 2*50a9bdd4SDavid du Colombier * 4th Edition p9any/p9sk1 authentication based on auth9p1.c 3*50a9bdd4SDavid du Colombier * Nigel Roles (nigel@9fs.org) 2003 4*50a9bdd4SDavid du Colombier */ 5*50a9bdd4SDavid du Colombier 6*50a9bdd4SDavid du Colombier #include <plan9.h> 7*50a9bdd4SDavid du Colombier #include <fcall.h> 8*50a9bdd4SDavid du Colombier #include <u9fs.h> 9*50a9bdd4SDavid du Colombier #include <stdlib.h> /* for random stuff */ 10*50a9bdd4SDavid du Colombier 11*50a9bdd4SDavid du Colombier typedef struct Ticket Ticket; 12*50a9bdd4SDavid du Colombier typedef struct Ticketreq Ticketreq; 13*50a9bdd4SDavid du Colombier typedef struct Authenticator Authenticator; 14*50a9bdd4SDavid du Colombier 15*50a9bdd4SDavid du Colombier enum 16*50a9bdd4SDavid du Colombier { 17*50a9bdd4SDavid du Colombier DOMLEN= 48, /* length of an authentication domain name */ 18*50a9bdd4SDavid du Colombier DESKEYLEN= 7, /* length of a des key for encrypt/decrypt */ 19*50a9bdd4SDavid du Colombier CHALLEN= 8 /* length of a challenge */ 20*50a9bdd4SDavid du Colombier }; 21*50a9bdd4SDavid du Colombier 22*50a9bdd4SDavid du Colombier enum { 23*50a9bdd4SDavid du Colombier HaveProtos, 24*50a9bdd4SDavid du Colombier NeedProto, 25*50a9bdd4SDavid du Colombier NeedChal, 26*50a9bdd4SDavid du Colombier HaveTreq, 27*50a9bdd4SDavid du Colombier NeedTicket, 28*50a9bdd4SDavid du Colombier HaveAuth, 29*50a9bdd4SDavid du Colombier Established, 30*50a9bdd4SDavid du Colombier }; 31*50a9bdd4SDavid du Colombier 32*50a9bdd4SDavid du Colombier /* encryption numberings (anti-replay) */ 33*50a9bdd4SDavid du Colombier enum 34*50a9bdd4SDavid du Colombier { 35*50a9bdd4SDavid du Colombier AuthTreq=1, /* ticket request */ 36*50a9bdd4SDavid du Colombier AuthChal=2, /* challenge box request */ 37*50a9bdd4SDavid du Colombier AuthPass=3, /* change password */ 38*50a9bdd4SDavid du Colombier AuthOK=4, /* fixed length reply follows */ 39*50a9bdd4SDavid du Colombier AuthErr=5, /* error follows */ 40*50a9bdd4SDavid du Colombier AuthMod=6, /* modify user */ 41*50a9bdd4SDavid du Colombier AuthApop=7, /* apop authentication for pop3 */ 42*50a9bdd4SDavid du Colombier AuthOKvar=9, /* variable length reply follows */ 43*50a9bdd4SDavid du Colombier AuthChap=10, /* chap authentication for ppp */ 44*50a9bdd4SDavid du Colombier AuthMSchap=11, /* MS chap authentication for ppp */ 45*50a9bdd4SDavid du Colombier AuthCram=12, /* CRAM verification for IMAP (RFC2195 & rfc2104) */ 46*50a9bdd4SDavid du Colombier AuthHttp=13, /* http domain login */ 47*50a9bdd4SDavid du Colombier AuthVNC=14, /* http domain login */ 48*50a9bdd4SDavid du Colombier 49*50a9bdd4SDavid du Colombier 50*50a9bdd4SDavid du Colombier AuthTs=64, /* ticket encrypted with server's key */ 51*50a9bdd4SDavid du Colombier AuthTc, /* ticket encrypted with client's key */ 52*50a9bdd4SDavid du Colombier AuthAs, /* server generated authenticator */ 53*50a9bdd4SDavid du Colombier AuthAc, /* client generated authenticator */ 54*50a9bdd4SDavid du Colombier AuthTp, /* ticket encrypted with client's key for password change */ 55*50a9bdd4SDavid du Colombier AuthHr /* http reply */ 56*50a9bdd4SDavid du Colombier }; 57*50a9bdd4SDavid du Colombier 58*50a9bdd4SDavid du Colombier struct Ticketreq 59*50a9bdd4SDavid du Colombier { 60*50a9bdd4SDavid du Colombier char type; 61*50a9bdd4SDavid du Colombier char authid[NAMELEN]; /* server's encryption id */ 62*50a9bdd4SDavid du Colombier char authdom[DOMLEN]; /* server's authentication domain */ 63*50a9bdd4SDavid du Colombier char chal[CHALLEN]; /* challenge from server */ 64*50a9bdd4SDavid du Colombier char hostid[NAMELEN]; /* host's encryption id */ 65*50a9bdd4SDavid du Colombier char uid[NAMELEN]; /* uid of requesting user on host */ 66*50a9bdd4SDavid du Colombier }; 67*50a9bdd4SDavid du Colombier #define TICKREQLEN (3*NAMELEN+CHALLEN+DOMLEN+1) 68*50a9bdd4SDavid du Colombier 69*50a9bdd4SDavid du Colombier struct Ticket 70*50a9bdd4SDavid du Colombier { 71*50a9bdd4SDavid du Colombier char num; /* replay protection */ 72*50a9bdd4SDavid du Colombier char chal[CHALLEN]; /* server challenge */ 73*50a9bdd4SDavid du Colombier char cuid[NAMELEN]; /* uid on client */ 74*50a9bdd4SDavid du Colombier char suid[NAMELEN]; /* uid on server */ 75*50a9bdd4SDavid du Colombier char key[DESKEYLEN]; /* nonce DES key */ 76*50a9bdd4SDavid du Colombier }; 77*50a9bdd4SDavid du Colombier #define TICKETLEN (CHALLEN+2*NAMELEN+DESKEYLEN+1) 78*50a9bdd4SDavid du Colombier 79*50a9bdd4SDavid du Colombier struct Authenticator 80*50a9bdd4SDavid du Colombier { 81*50a9bdd4SDavid du Colombier char num; /* replay protection */ 82*50a9bdd4SDavid du Colombier char chal[CHALLEN]; 83*50a9bdd4SDavid du Colombier ulong id; /* authenticator id, ++'d with each auth */ 84*50a9bdd4SDavid du Colombier }; 85*50a9bdd4SDavid du Colombier #define AUTHENTLEN (CHALLEN+4+1) 86*50a9bdd4SDavid du Colombier 87*50a9bdd4SDavid du Colombier static int convT2M(Ticket*, char*, char*); 88*50a9bdd4SDavid du Colombier static void convM2T(char*, Ticket*, char*); 89*50a9bdd4SDavid du Colombier static void convM2Tnoenc(char*, Ticket*); 90*50a9bdd4SDavid du Colombier static int convA2M(Authenticator*, char*, char*); 91*50a9bdd4SDavid du Colombier static void convM2A(char*, Authenticator*, char*); 92*50a9bdd4SDavid du Colombier static int convTR2M(Ticketreq*, char*); 93*50a9bdd4SDavid du Colombier static void convM2TR(char*, Ticketreq*); 94*50a9bdd4SDavid du Colombier static int passtokey(char*, char*); 95*50a9bdd4SDavid du Colombier 96*50a9bdd4SDavid du Colombier /* 97*50a9bdd4SDavid du Colombier * Data Encryption Standard 98*50a9bdd4SDavid du Colombier * D.P.Mitchell 83/06/08. 99*50a9bdd4SDavid du Colombier * 100*50a9bdd4SDavid du Colombier * block_cipher(key, block, decrypting) 101*50a9bdd4SDavid du Colombier */ 102*50a9bdd4SDavid du Colombier 103*50a9bdd4SDavid du Colombier static long ip_low(char [8]); 104*50a9bdd4SDavid du Colombier static long ip_high(char [8]); 105*50a9bdd4SDavid du Colombier static void fp(long, long, char[8]); 106*50a9bdd4SDavid du Colombier static void key_setup(char[DESKEYLEN], char[128]); 107*50a9bdd4SDavid du Colombier static void block_cipher(char[128], char[8], int); 108*50a9bdd4SDavid du Colombier 109*50a9bdd4SDavid du Colombier extern int chatty9p; 110*50a9bdd4SDavid du Colombier 111*50a9bdd4SDavid du Colombier /* 112*50a9bdd4SDavid du Colombier * destructively encrypt the buffer, which 113*50a9bdd4SDavid du Colombier * must be at least 8 characters long. 114*50a9bdd4SDavid du Colombier */ 115*50a9bdd4SDavid du Colombier static int 116*50a9bdd4SDavid du Colombier encrypt9p(void *key, void *vbuf, int n) 117*50a9bdd4SDavid du Colombier { 118*50a9bdd4SDavid du Colombier char ekey[128], *buf; 119*50a9bdd4SDavid du Colombier int i, r; 120*50a9bdd4SDavid du Colombier 121*50a9bdd4SDavid du Colombier if(n < 8) 122*50a9bdd4SDavid du Colombier return 0; 123*50a9bdd4SDavid du Colombier key_setup(key, ekey); 124*50a9bdd4SDavid du Colombier buf = vbuf; 125*50a9bdd4SDavid du Colombier n--; 126*50a9bdd4SDavid du Colombier r = n % 7; 127*50a9bdd4SDavid du Colombier n /= 7; 128*50a9bdd4SDavid du Colombier for(i = 0; i < n; i++){ 129*50a9bdd4SDavid du Colombier block_cipher(ekey, buf, 0); 130*50a9bdd4SDavid du Colombier buf += 7; 131*50a9bdd4SDavid du Colombier } 132*50a9bdd4SDavid du Colombier if(r) 133*50a9bdd4SDavid du Colombier block_cipher(ekey, buf - 7 + r, 0); 134*50a9bdd4SDavid du Colombier return 1; 135*50a9bdd4SDavid du Colombier } 136*50a9bdd4SDavid du Colombier 137*50a9bdd4SDavid du Colombier /* 138*50a9bdd4SDavid du Colombier * destructively decrypt the buffer, which 139*50a9bdd4SDavid du Colombier * must be at least 8 characters long. 140*50a9bdd4SDavid du Colombier */ 141*50a9bdd4SDavid du Colombier static int 142*50a9bdd4SDavid du Colombier decrypt9p(void *key, void *vbuf, int n) 143*50a9bdd4SDavid du Colombier { 144*50a9bdd4SDavid du Colombier char ekey[128], *buf; 145*50a9bdd4SDavid du Colombier int i, r; 146*50a9bdd4SDavid du Colombier 147*50a9bdd4SDavid du Colombier if(n < 8) 148*50a9bdd4SDavid du Colombier return 0; 149*50a9bdd4SDavid du Colombier key_setup(key, ekey); 150*50a9bdd4SDavid du Colombier buf = vbuf; 151*50a9bdd4SDavid du Colombier n--; 152*50a9bdd4SDavid du Colombier r = n % 7; 153*50a9bdd4SDavid du Colombier n /= 7; 154*50a9bdd4SDavid du Colombier buf += n * 7; 155*50a9bdd4SDavid du Colombier if(r) 156*50a9bdd4SDavid du Colombier block_cipher(ekey, buf - 7 + r, 1); 157*50a9bdd4SDavid du Colombier for(i = 0; i < n; i++){ 158*50a9bdd4SDavid du Colombier buf -= 7; 159*50a9bdd4SDavid du Colombier block_cipher(ekey, buf, 1); 160*50a9bdd4SDavid du Colombier } 161*50a9bdd4SDavid du Colombier return 1; 162*50a9bdd4SDavid du Colombier } 163*50a9bdd4SDavid du Colombier 164*50a9bdd4SDavid du Colombier /* 165*50a9bdd4SDavid du Colombier * Tables for Combined S and P Boxes 166*50a9bdd4SDavid du Colombier */ 167*50a9bdd4SDavid du Colombier 168*50a9bdd4SDavid du Colombier static long s0p[] = { 169*50a9bdd4SDavid du Colombier 0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000, 170*50a9bdd4SDavid du Colombier 0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000, 171*50a9bdd4SDavid du Colombier 0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100, 172*50a9bdd4SDavid du Colombier 0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000, 173*50a9bdd4SDavid du Colombier 0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100, 174*50a9bdd4SDavid du Colombier 0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000, 175*50a9bdd4SDavid du Colombier 0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000, 176*50a9bdd4SDavid du Colombier 0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100, 177*50a9bdd4SDavid du Colombier }; 178*50a9bdd4SDavid du Colombier 179*50a9bdd4SDavid du Colombier static long s1p[] = { 180*50a9bdd4SDavid du Colombier 0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000, 181*50a9bdd4SDavid du Colombier 0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002, 182*50a9bdd4SDavid du Colombier 0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002, 183*50a9bdd4SDavid du Colombier 0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002, 184*50a9bdd4SDavid du Colombier 0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000, 185*50a9bdd4SDavid du Colombier 0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002, 186*50a9bdd4SDavid du Colombier 0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000, 187*50a9bdd4SDavid du Colombier 0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000, 188*50a9bdd4SDavid du Colombier }; 189*50a9bdd4SDavid du Colombier 190*50a9bdd4SDavid du Colombier static long s2p[] = { 191*50a9bdd4SDavid du Colombier 0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020, 192*50a9bdd4SDavid du Colombier 0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000, 193*50a9bdd4SDavid du Colombier 0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000, 194*50a9bdd4SDavid du Colombier 0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020, 195*50a9bdd4SDavid du Colombier 0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020, 196*50a9bdd4SDavid du Colombier 0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000, 197*50a9bdd4SDavid du Colombier 0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020, 198*50a9bdd4SDavid du Colombier 0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000, 199*50a9bdd4SDavid du Colombier }; 200*50a9bdd4SDavid du Colombier 201*50a9bdd4SDavid du Colombier static long s3p[] = { 202*50a9bdd4SDavid du Colombier 0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001, 203*50a9bdd4SDavid du Colombier 0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000, 204*50a9bdd4SDavid du Colombier 0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200, 205*50a9bdd4SDavid du Colombier 0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000, 206*50a9bdd4SDavid du Colombier 0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000, 207*50a9bdd4SDavid du Colombier 0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200, 208*50a9bdd4SDavid du Colombier 0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201, 209*50a9bdd4SDavid du Colombier 0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200, 210*50a9bdd4SDavid du Colombier }; 211*50a9bdd4SDavid du Colombier 212*50a9bdd4SDavid du Colombier static long s4p[] = { 213*50a9bdd4SDavid du Colombier 0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000, 214*50a9bdd4SDavid du Colombier 0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000, 215*50a9bdd4SDavid du Colombier 0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004, 216*50a9bdd4SDavid du Colombier 0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080, 217*50a9bdd4SDavid du Colombier 0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080, 218*50a9bdd4SDavid du Colombier 0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004, 219*50a9bdd4SDavid du Colombier 0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000, 220*50a9bdd4SDavid du Colombier 0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004, 221*50a9bdd4SDavid du Colombier }; 222*50a9bdd4SDavid du Colombier 223*50a9bdd4SDavid du Colombier static long s5p[] = { 224*50a9bdd4SDavid du Colombier 0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000, 225*50a9bdd4SDavid du Colombier 0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408, 226*50a9bdd4SDavid du Colombier 0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008, 227*50a9bdd4SDavid du Colombier 0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400, 228*50a9bdd4SDavid du Colombier 0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400, 229*50a9bdd4SDavid du Colombier 0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008, 230*50a9bdd4SDavid du Colombier 0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000, 231*50a9bdd4SDavid du Colombier 0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008, 232*50a9bdd4SDavid du Colombier }; 233*50a9bdd4SDavid du Colombier 234*50a9bdd4SDavid du Colombier static long s6p[] = { 235*50a9bdd4SDavid du Colombier 0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000, 236*50a9bdd4SDavid du Colombier 0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040, 237*50a9bdd4SDavid du Colombier 0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840, 238*50a9bdd4SDavid du Colombier 0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000, 239*50a9bdd4SDavid du Colombier 0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800, 240*50a9bdd4SDavid du Colombier 0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040, 241*50a9bdd4SDavid du Colombier 0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000, 242*50a9bdd4SDavid du Colombier 0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800, 243*50a9bdd4SDavid du Colombier }; 244*50a9bdd4SDavid du Colombier 245*50a9bdd4SDavid du Colombier static long s7p[] = { 246*50a9bdd4SDavid du Colombier 0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010, 247*50a9bdd4SDavid du Colombier 0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000, 248*50a9bdd4SDavid du Colombier 0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000, 249*50a9bdd4SDavid du Colombier 0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010, 250*50a9bdd4SDavid du Colombier 0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000, 251*50a9bdd4SDavid du Colombier 0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000, 252*50a9bdd4SDavid du Colombier 0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000, 253*50a9bdd4SDavid du Colombier 0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010, 254*50a9bdd4SDavid du Colombier }; 255*50a9bdd4SDavid du Colombier 256*50a9bdd4SDavid du Colombier /* 257*50a9bdd4SDavid du Colombier * DES electronic codebook encryption of one block 258*50a9bdd4SDavid du Colombier */ 259*50a9bdd4SDavid du Colombier static void 260*50a9bdd4SDavid du Colombier block_cipher(char expanded_key[128], char text[8], int decrypting) 261*50a9bdd4SDavid du Colombier { 262*50a9bdd4SDavid du Colombier char *key; 263*50a9bdd4SDavid du Colombier long crypto, temp, right, left; 264*50a9bdd4SDavid du Colombier int i, key_offset; 265*50a9bdd4SDavid du Colombier 266*50a9bdd4SDavid du Colombier key = expanded_key; 267*50a9bdd4SDavid du Colombier left = ip_low(text); 268*50a9bdd4SDavid du Colombier right = ip_high(text); 269*50a9bdd4SDavid du Colombier if (decrypting) { 270*50a9bdd4SDavid du Colombier key_offset = 16; 271*50a9bdd4SDavid du Colombier key = key + 128 - 8; 272*50a9bdd4SDavid du Colombier } else 273*50a9bdd4SDavid du Colombier key_offset = 0; 274*50a9bdd4SDavid du Colombier for (i = 0; i < 16; i++) { 275*50a9bdd4SDavid du Colombier temp = (right << 1) | ((right >> 31) & 1); 276*50a9bdd4SDavid du Colombier crypto = s0p[(temp & 0x3f) ^ *key++]; 277*50a9bdd4SDavid du Colombier crypto |= s1p[((temp >> 4) & 0x3f) ^ *key++]; 278*50a9bdd4SDavid du Colombier crypto |= s2p[((temp >> 8) & 0x3f) ^ *key++]; 279*50a9bdd4SDavid du Colombier crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++]; 280*50a9bdd4SDavid du Colombier crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++]; 281*50a9bdd4SDavid du Colombier crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++]; 282*50a9bdd4SDavid du Colombier crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++]; 283*50a9bdd4SDavid du Colombier temp = ((right & 1) << 5) | ((right >> 27) & 0x1f); 284*50a9bdd4SDavid du Colombier crypto |= s7p[temp ^ *key++]; 285*50a9bdd4SDavid du Colombier temp = left; 286*50a9bdd4SDavid du Colombier left = right; 287*50a9bdd4SDavid du Colombier right = temp ^ crypto; 288*50a9bdd4SDavid du Colombier key -= key_offset; 289*50a9bdd4SDavid du Colombier } 290*50a9bdd4SDavid du Colombier /* 291*50a9bdd4SDavid du Colombier * standard final permutation (IPI) 292*50a9bdd4SDavid du Colombier * left and right are reversed here 293*50a9bdd4SDavid du Colombier */ 294*50a9bdd4SDavid du Colombier fp(right, left, text); 295*50a9bdd4SDavid du Colombier } 296*50a9bdd4SDavid du Colombier 297*50a9bdd4SDavid du Colombier /* 298*50a9bdd4SDavid du Colombier * Initial Permutation 299*50a9bdd4SDavid du Colombier */ 300*50a9bdd4SDavid du Colombier static long iptab[] = { 301*50a9bdd4SDavid du Colombier 0x00000000, 0x00008000, 0x00000000, 0x00008000, 302*50a9bdd4SDavid du Colombier 0x00000080, 0x00008080, 0x00000080, 0x00008080 303*50a9bdd4SDavid du Colombier }; 304*50a9bdd4SDavid du Colombier 305*50a9bdd4SDavid du Colombier static long 306*50a9bdd4SDavid du Colombier ip_low(char block[8]) 307*50a9bdd4SDavid du Colombier { 308*50a9bdd4SDavid du Colombier int i; 309*50a9bdd4SDavid du Colombier long l; 310*50a9bdd4SDavid du Colombier 311*50a9bdd4SDavid du Colombier l = 0; 312*50a9bdd4SDavid du Colombier for(i = 0; i < 8; i++){ 313*50a9bdd4SDavid du Colombier l |= iptab[(block[i] >> 4) & 7] >> i; 314*50a9bdd4SDavid du Colombier l |= iptab[block[i] & 7] << (16 - i); 315*50a9bdd4SDavid du Colombier } 316*50a9bdd4SDavid du Colombier return l; 317*50a9bdd4SDavid du Colombier } 318*50a9bdd4SDavid du Colombier 319*50a9bdd4SDavid du Colombier static long 320*50a9bdd4SDavid du Colombier ip_high(char block[8]) 321*50a9bdd4SDavid du Colombier { 322*50a9bdd4SDavid du Colombier int i; 323*50a9bdd4SDavid du Colombier long l; 324*50a9bdd4SDavid du Colombier 325*50a9bdd4SDavid du Colombier l = 0; 326*50a9bdd4SDavid du Colombier for(i = 0; i < 8; i++){ 327*50a9bdd4SDavid du Colombier l |= iptab[(block[i] >> 5) & 7] >> i; 328*50a9bdd4SDavid du Colombier l |= iptab[(block[i] >> 1) & 7] << (16 - i); 329*50a9bdd4SDavid du Colombier } 330*50a9bdd4SDavid du Colombier return l; 331*50a9bdd4SDavid du Colombier } 332*50a9bdd4SDavid du Colombier 333*50a9bdd4SDavid du Colombier /* 334*50a9bdd4SDavid du Colombier * Final Permutation 335*50a9bdd4SDavid du Colombier */ 336*50a9bdd4SDavid du Colombier static unsigned long fptab[] = { 337*50a9bdd4SDavid du Colombier 0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000, 338*50a9bdd4SDavid du Colombier 0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080, 339*50a9bdd4SDavid du Colombier }; 340*50a9bdd4SDavid du Colombier 341*50a9bdd4SDavid du Colombier static void 342*50a9bdd4SDavid du Colombier fp(long left, long right, char text[8]) 343*50a9bdd4SDavid du Colombier { 344*50a9bdd4SDavid du Colombier unsigned long ta[2], t, v[2]; 345*50a9bdd4SDavid du Colombier int i, j, sh; 346*50a9bdd4SDavid du Colombier 347*50a9bdd4SDavid du Colombier ta[0] = right; 348*50a9bdd4SDavid du Colombier ta[1] = left; 349*50a9bdd4SDavid du Colombier v[0] = v[1] = 0; 350*50a9bdd4SDavid du Colombier for(i = 0; i < 2; i++){ 351*50a9bdd4SDavid du Colombier t = ta[i]; 352*50a9bdd4SDavid du Colombier sh = i; 353*50a9bdd4SDavid du Colombier for(j = 0; j < 4; j++){ 354*50a9bdd4SDavid du Colombier v[1] |= fptab[t & 0xf] >> sh; 355*50a9bdd4SDavid du Colombier t >>= 4; 356*50a9bdd4SDavid du Colombier v[0] |= fptab[t & 0xf] >> sh; 357*50a9bdd4SDavid du Colombier t >>= 4; 358*50a9bdd4SDavid du Colombier sh += 2; 359*50a9bdd4SDavid du Colombier } 360*50a9bdd4SDavid du Colombier } 361*50a9bdd4SDavid du Colombier for(i = 0; i < 2; i++) 362*50a9bdd4SDavid du Colombier for(j = 0; j < 4; j++){ 363*50a9bdd4SDavid du Colombier *text++ = v[i]; 364*50a9bdd4SDavid du Colombier v[i] >>= 8; 365*50a9bdd4SDavid du Colombier } 366*50a9bdd4SDavid du Colombier } 367*50a9bdd4SDavid du Colombier 368*50a9bdd4SDavid du Colombier /* 369*50a9bdd4SDavid du Colombier * Key set-up 370*50a9bdd4SDavid du Colombier */ 371*50a9bdd4SDavid du Colombier static uchar keyexpand[][15][2] = { 372*50a9bdd4SDavid du Colombier { 3, 2, 9, 8, 18, 8, 27, 32, 33, 2, 42, 16, 48, 8, 65, 16, 373*50a9bdd4SDavid du Colombier 74, 2, 80, 2, 89, 4, 99, 16, 104, 4, 122, 32, 0, 0, }, 374*50a9bdd4SDavid du Colombier { 1, 4, 8, 1, 18, 4, 25, 32, 34, 32, 41, 8, 50, 8, 59, 32, 375*50a9bdd4SDavid du Colombier 64, 16, 75, 4, 90, 1, 97, 16, 106, 2, 112, 2, 123, 1, }, 376*50a9bdd4SDavid du Colombier { 2, 1, 19, 8, 35, 1, 40, 1, 50, 4, 57, 32, 75, 2, 80, 32, 377*50a9bdd4SDavid du Colombier 89, 1, 96, 16, 107, 4, 120, 8, 0, 0, 0, 0, 0, 0, }, 378*50a9bdd4SDavid du Colombier { 4, 32, 20, 2, 31, 4, 37, 32, 47, 1, 54, 1, 63, 2, 68, 1, 379*50a9bdd4SDavid du Colombier 78, 4, 84, 8, 101, 16, 108, 4, 119, 16, 126, 8, 0, 0, }, 380*50a9bdd4SDavid du Colombier { 5, 4, 15, 4, 21, 32, 31, 1, 38, 1, 47, 2, 53, 2, 68, 8, 381*50a9bdd4SDavid du Colombier 85, 16, 92, 4, 103, 16, 108, 32, 118, 32, 124, 2, 0, 0, }, 382*50a9bdd4SDavid du Colombier { 15, 2, 21, 2, 39, 8, 46, 16, 55, 32, 61, 1, 71, 16, 76, 32, 383*50a9bdd4SDavid du Colombier 86, 32, 93, 4, 102, 2, 108, 16, 117, 8, 126, 1, 0, 0, }, 384*50a9bdd4SDavid du Colombier { 14, 16, 23, 32, 29, 1, 38, 8, 52, 2, 63, 4, 70, 2, 76, 16, 385*50a9bdd4SDavid du Colombier 85, 8, 100, 1, 110, 4, 116, 8, 127, 8, 0, 0, 0, 0, }, 386*50a9bdd4SDavid du Colombier { 1, 8, 8, 32, 17, 1, 24, 16, 35, 4, 50, 1, 57, 16, 67, 8, 387*50a9bdd4SDavid du Colombier 83, 1, 88, 1, 98, 4, 105, 32, 114, 32, 123, 2, 0, 0, }, 388*50a9bdd4SDavid du Colombier { 0, 1, 11, 16, 16, 4, 35, 2, 40, 32, 49, 1, 56, 16, 65, 2, 389*50a9bdd4SDavid du Colombier 74, 16, 80, 8, 99, 8, 115, 1, 121, 4, 0, 0, 0, 0, }, 390*50a9bdd4SDavid du Colombier { 9, 16, 18, 2, 24, 2, 33, 4, 43, 16, 48, 4, 66, 32, 73, 8, 391*50a9bdd4SDavid du Colombier 82, 8, 91, 32, 97, 2, 106, 16, 112, 8, 122, 1, 0, 0, }, 392*50a9bdd4SDavid du Colombier { 14, 32, 21, 4, 30, 2, 36, 16, 45, 8, 60, 1, 69, 2, 87, 8, 393*50a9bdd4SDavid du Colombier 94, 16, 103, 32, 109, 1, 118, 8, 124, 32, 0, 0, 0, 0, }, 394*50a9bdd4SDavid du Colombier { 7, 4, 14, 2, 20, 16, 29, 8, 44, 1, 54, 4, 60, 8, 71, 8, 395*50a9bdd4SDavid du Colombier 78, 16, 87, 32, 93, 1, 102, 8, 116, 2, 125, 4, 0, 0, }, 396*50a9bdd4SDavid du Colombier { 7, 2, 12, 1, 22, 4, 28, 8, 45, 16, 52, 4, 63, 16, 70, 8, 397*50a9bdd4SDavid du Colombier 84, 2, 95, 4, 101, 32, 111, 1, 118, 1, 0, 0, 0, 0, }, 398*50a9bdd4SDavid du Colombier { 6, 16, 13, 16, 20, 4, 31, 16, 36, 32, 46, 32, 53, 4, 62, 2, 399*50a9bdd4SDavid du Colombier 69, 32, 79, 1, 86, 1, 95, 2, 101, 2, 119, 8, 0, 0, }, 400*50a9bdd4SDavid du Colombier { 0, 32, 10, 8, 19, 32, 25, 2, 34, 16, 40, 8, 59, 8, 66, 2, 401*50a9bdd4SDavid du Colombier 72, 2, 81, 4, 91, 16, 96, 4, 115, 2, 121, 8, 0, 0, }, 402*50a9bdd4SDavid du Colombier { 3, 16, 10, 4, 17, 32, 26, 32, 33, 8, 42, 8, 51, 32, 57, 2, 403*50a9bdd4SDavid du Colombier 67, 4, 82, 1, 89, 16, 98, 2, 104, 2, 113, 4, 120, 1, }, 404*50a9bdd4SDavid du Colombier { 1, 16, 11, 8, 27, 1, 32, 1, 42, 4, 49, 32, 58, 32, 67, 2, 405*50a9bdd4SDavid du Colombier 72, 32, 81, 1, 88, 16, 99, 4, 114, 1, 0, 0, 0, 0, }, 406*50a9bdd4SDavid du Colombier { 6, 32, 12, 2, 23, 4, 29, 32, 39, 1, 46, 1, 55, 2, 61, 2, 407*50a9bdd4SDavid du Colombier 70, 4, 76, 8, 93, 16, 100, 4, 111, 16, 116, 32, 0, 0, }, 408*50a9bdd4SDavid du Colombier { 6, 2, 13, 32, 23, 1, 30, 1, 39, 2, 45, 2, 63, 8, 77, 16, 409*50a9bdd4SDavid du Colombier 84, 4, 95, 16, 100, 32, 110, 32, 117, 4, 127, 4, 0, 0, }, 410*50a9bdd4SDavid du Colombier { 4, 1, 13, 2, 31, 8, 38, 16, 47, 32, 53, 1, 62, 8, 68, 32, 411*50a9bdd4SDavid du Colombier 78, 32, 85, 4, 94, 2, 100, 16, 109, 8, 127, 2, 0, 0, }, 412*50a9bdd4SDavid du Colombier { 5, 16, 15, 32, 21, 1, 30, 8, 44, 2, 55, 4, 61, 32, 68, 16, 413*50a9bdd4SDavid du Colombier 77, 8, 92, 1, 102, 4, 108, 8, 126, 16, 0, 0, 0, 0, }, 414*50a9bdd4SDavid du Colombier { 2, 8, 9, 1, 16, 16, 27, 4, 42, 1, 49, 16, 58, 2, 75, 1, 415*50a9bdd4SDavid du Colombier 80, 1, 90, 4, 97, 32, 106, 32, 113, 8, 120, 32, 0, 0, }, 416*50a9bdd4SDavid du Colombier { 2, 4, 8, 4, 27, 2, 32, 32, 41, 1, 48, 16, 59, 4, 66, 16, 417*50a9bdd4SDavid du Colombier 72, 8, 91, 8, 107, 1, 112, 1, 123, 16, 0, 0, 0, 0, }, 418*50a9bdd4SDavid du Colombier { 3, 8, 10, 2, 16, 2, 25, 4, 35, 16, 40, 4, 59, 2, 65, 8, 419*50a9bdd4SDavid du Colombier 74, 8, 83, 32, 89, 2, 98, 16, 104, 8, 121, 16, 0, 0, }, 420*50a9bdd4SDavid du Colombier { 4, 2, 13, 4, 22, 2, 28, 16, 37, 8, 52, 1, 62, 4, 79, 8, 421*50a9bdd4SDavid du Colombier 86, 16, 95, 32, 101, 1, 110, 8, 126, 32, 0, 0, 0, 0, }, 422*50a9bdd4SDavid du Colombier { 5, 32, 12, 16, 21, 8, 36, 1, 46, 4, 52, 8, 70, 16, 79, 32, 423*50a9bdd4SDavid du Colombier 85, 1, 94, 8, 108, 2, 119, 4, 126, 2, 0, 0, 0, 0, }, 424*50a9bdd4SDavid du Colombier { 5, 2, 14, 4, 20, 8, 37, 16, 44, 4, 55, 16, 60, 32, 76, 2, 425*50a9bdd4SDavid du Colombier 87, 4, 93, 32, 103, 1, 110, 1, 119, 2, 124, 1, 0, 0, }, 426*50a9bdd4SDavid du Colombier { 7, 32, 12, 4, 23, 16, 28, 32, 38, 32, 45, 4, 54, 2, 60, 16, 427*50a9bdd4SDavid du Colombier 71, 1, 78, 1, 87, 2, 93, 2, 111, 8, 118, 16, 125, 16, }, 428*50a9bdd4SDavid du Colombier { 1, 1, 11, 32, 17, 2, 26, 16, 32, 8, 51, 8, 64, 2, 73, 4, 429*50a9bdd4SDavid du Colombier 83, 16, 88, 4, 107, 2, 112, 32, 122, 8, 0, 0, 0, 0, }, 430*50a9bdd4SDavid du Colombier { 0, 4, 9, 32, 18, 32, 25, 8, 34, 8, 43, 32, 49, 2, 58, 16, 431*50a9bdd4SDavid du Colombier 74, 1, 81, 16, 90, 2, 96, 2, 105, 4, 115, 16, 122, 4, }, 432*50a9bdd4SDavid du Colombier { 2, 2, 19, 1, 24, 1, 34, 4, 41, 32, 50, 32, 57, 8, 64, 32, 433*50a9bdd4SDavid du Colombier 73, 1, 80, 16, 91, 4, 106, 1, 113, 16, 123, 8, 0, 0, }, 434*50a9bdd4SDavid du Colombier { 3, 4, 10, 16, 16, 8, 35, 8, 51, 1, 56, 1, 67, 16, 72, 4, 435*50a9bdd4SDavid du Colombier 91, 2, 96, 32, 105, 1, 112, 16, 121, 2, 0, 0, 0, 0, }, 436*50a9bdd4SDavid du Colombier { 4, 16, 15, 1, 22, 1, 31, 2, 37, 2, 55, 8, 62, 16, 69, 16, 437*50a9bdd4SDavid du Colombier 76, 4, 87, 16, 92, 32, 102, 32, 109, 4, 118, 2, 125, 32, }, 438*50a9bdd4SDavid du Colombier { 6, 4, 23, 8, 30, 16, 39, 32, 45, 1, 54, 8, 70, 32, 77, 4, 439*50a9bdd4SDavid du Colombier 86, 2, 92, 16, 101, 8, 116, 1, 125, 2, 0, 0, 0, 0, }, 440*50a9bdd4SDavid du Colombier { 4, 4, 13, 1, 22, 8, 36, 2, 47, 4, 53, 32, 63, 1, 69, 8, 441*50a9bdd4SDavid du Colombier 84, 1, 94, 4, 100, 8, 117, 16, 127, 32, 0, 0, 0, 0, }, 442*50a9bdd4SDavid du Colombier { 3, 32, 8, 16, 19, 4, 34, 1, 41, 16, 50, 2, 56, 2, 67, 1, 443*50a9bdd4SDavid du Colombier 72, 1, 82, 4, 89, 32, 98, 32, 105, 8, 114, 8, 121, 1, }, 444*50a9bdd4SDavid du Colombier { 1, 32, 19, 2, 24, 32, 33, 1, 40, 16, 51, 4, 64, 8, 83, 8, 445*50a9bdd4SDavid du Colombier 99, 1, 104, 1, 114, 4, 120, 4, 0, 0, 0, 0, 0, 0, }, 446*50a9bdd4SDavid du Colombier { 8, 2, 17, 4, 27, 16, 32, 4, 51, 2, 56, 32, 66, 8, 75, 32, 447*50a9bdd4SDavid du Colombier 81, 2, 90, 16, 96, 8, 115, 8, 122, 2, 0, 0, 0, 0, }, 448*50a9bdd4SDavid du Colombier { 2, 16, 18, 1, 25, 16, 34, 2, 40, 2, 49, 4, 59, 16, 66, 4, 449*50a9bdd4SDavid du Colombier 73, 32, 82, 32, 89, 8, 98, 8, 107, 32, 113, 2, 123, 4, }, 450*50a9bdd4SDavid du Colombier { 7, 1, 13, 8, 28, 1, 38, 4, 44, 8, 61, 16, 71, 32, 77, 1, 451*50a9bdd4SDavid du Colombier 86, 8, 100, 2, 111, 4, 117, 32, 124, 16, 0, 0, 0, 0, }, 452*50a9bdd4SDavid du Colombier { 12, 8, 29, 16, 36, 4, 47, 16, 52, 32, 62, 32, 68, 2, 79, 4, 453*50a9bdd4SDavid du Colombier 85, 32, 95, 1, 102, 1, 111, 2, 117, 2, 126, 4, 0, 0, }, 454*50a9bdd4SDavid du Colombier { 5, 1, 15, 16, 20, 32, 30, 32, 37, 4, 46, 2, 52, 16, 61, 8, 455*50a9bdd4SDavid du Colombier 70, 1, 79, 2, 85, 2, 103, 8, 110, 16, 119, 32, 124, 4, }, 456*50a9bdd4SDavid du Colombier { 0, 16, 9, 2, 18, 16, 24, 8, 43, 8, 59, 1, 65, 4, 75, 16, 457*50a9bdd4SDavid du Colombier 80, 4, 99, 2, 104, 32, 113, 1, 123, 32, 0, 0, 0, 0, }, 458*50a9bdd4SDavid du Colombier { 10, 32, 17, 8, 26, 8, 35, 32, 41, 2, 50, 16, 56, 8, 66, 1, 459*50a9bdd4SDavid du Colombier 73, 16, 82, 2, 88, 2, 97, 4, 107, 16, 112, 4, 121, 32, }, 460*50a9bdd4SDavid du Colombier { 0, 2, 11, 1, 16, 1, 26, 4, 33, 32, 42, 32, 49, 8, 58, 8, 461*50a9bdd4SDavid du Colombier 65, 1, 72, 16, 83, 4, 98, 1, 105, 16, 114, 2, 0, 0, }, 462*50a9bdd4SDavid du Colombier { 8, 8, 27, 8, 43, 1, 48, 1, 58, 4, 64, 4, 83, 2, 88, 32, 463*50a9bdd4SDavid du Colombier 97, 1, 104, 16, 115, 4, 122, 16, 0, 0, 0, 0, 0, 0, }, 464*50a9bdd4SDavid du Colombier { 5, 8, 14, 1, 23, 2, 29, 2, 47, 8, 54, 16, 63, 32, 68, 4, 465*50a9bdd4SDavid du Colombier 79, 16, 84, 32, 94, 32, 101, 4, 110, 2, 116, 16, 127, 1, }, 466*50a9bdd4SDavid du Colombier { 4, 8, 15, 8, 22, 16, 31, 32, 37, 1, 46, 8, 60, 2, 69, 4, 467*50a9bdd4SDavid du Colombier 78, 2, 84, 16, 93, 8, 108, 1, 118, 4, 0, 0, 0, 0, }, 468*50a9bdd4SDavid du Colombier { 7, 16, 14, 8, 28, 2, 39, 4, 45, 32, 55, 1, 62, 1, 76, 1, 469*50a9bdd4SDavid du Colombier 86, 4, 92, 8, 109, 16, 116, 4, 125, 1, 0, 0, 0, 0, }, 470*50a9bdd4SDavid du Colombier { 1, 2, 11, 4, 26, 1, 33, 16, 42, 2, 48, 2, 57, 4, 64, 1, 471*50a9bdd4SDavid du Colombier 74, 4, 81, 32, 90, 32, 97, 8, 106, 8, 115, 32, 120, 16, }, 472*50a9bdd4SDavid du Colombier { 2, 32, 11, 2, 16, 32, 25, 1, 32, 16, 43, 4, 58, 1, 75, 8, 473*50a9bdd4SDavid du Colombier 91, 1, 96, 1, 106, 4, 113, 32, 0, 0, 0, 0, 0, 0, }, 474*50a9bdd4SDavid du Colombier { 3, 1, 9, 4, 19, 16, 24, 4, 43, 2, 48, 32, 57, 1, 67, 32, 475*50a9bdd4SDavid du Colombier 73, 2, 82, 16, 88, 8, 107, 8, 120, 2, 0, 0, 0, 0, }, 476*50a9bdd4SDavid du Colombier { 0, 8, 10, 1, 17, 16, 26, 2, 32, 2, 41, 4, 51, 16, 56, 4, 477*50a9bdd4SDavid du Colombier 65, 32, 74, 32, 81, 8, 90, 8, 99, 32, 105, 2, 114, 16, }, 478*50a9bdd4SDavid du Colombier { 6, 1, 20, 1, 30, 4, 36, 8, 53, 16, 60, 4, 69, 1, 78, 8, 479*50a9bdd4SDavid du Colombier 92, 2, 103, 4, 109, 32, 119, 1, 125, 8, 0, 0, 0, 0, }, 480*50a9bdd4SDavid du Colombier { 7, 8, 21, 16, 28, 4, 39, 16, 44, 32, 54, 32, 61, 4, 71, 4, 481*50a9bdd4SDavid du Colombier 77, 32, 87, 1, 94, 1, 103, 2, 109, 2, 124, 8, 0, 0, }, 482*50a9bdd4SDavid du Colombier { 6, 8, 12, 32, 22, 32, 29, 4, 38, 2, 44, 16, 53, 8, 71, 2, 483*50a9bdd4SDavid du Colombier 77, 2, 95, 8, 102, 16, 111, 32, 117, 1, 127, 16, 0, 0, } 484*50a9bdd4SDavid du Colombier }; 485*50a9bdd4SDavid du Colombier 486*50a9bdd4SDavid du Colombier static void 487*50a9bdd4SDavid du Colombier key_setup(char key[DESKEYLEN], char *ek) 488*50a9bdd4SDavid du Colombier { 489*50a9bdd4SDavid du Colombier int i, j, k, mask; 490*50a9bdd4SDavid du Colombier uchar (*x)[2]; 491*50a9bdd4SDavid du Colombier 492*50a9bdd4SDavid du Colombier memset(ek, 0, 128); 493*50a9bdd4SDavid du Colombier x = keyexpand[0]; 494*50a9bdd4SDavid du Colombier for(i = 0; i < 7; i++){ 495*50a9bdd4SDavid du Colombier k = key[i]; 496*50a9bdd4SDavid du Colombier for(mask = 0x80; mask; mask >>= 1){ 497*50a9bdd4SDavid du Colombier if(k & mask) 498*50a9bdd4SDavid du Colombier for(j = 0; j < 15; j++) 499*50a9bdd4SDavid du Colombier ek[x[j][0]] |= x[j][1]; 500*50a9bdd4SDavid du Colombier x += 15; 501*50a9bdd4SDavid du Colombier } 502*50a9bdd4SDavid du Colombier } 503*50a9bdd4SDavid du Colombier } 504*50a9bdd4SDavid du Colombier 505*50a9bdd4SDavid du Colombier #define CHAR(x) *p++ = f->x 506*50a9bdd4SDavid du Colombier #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 507*50a9bdd4SDavid du Colombier #define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 508*50a9bdd4SDavid du Colombier #define LONG(x) VLONG(f->x) 509*50a9bdd4SDavid du Colombier #define STRING(x,n) memmove(p, f->x, n); p += n 510*50a9bdd4SDavid du Colombier 511*50a9bdd4SDavid du Colombier static int 512*50a9bdd4SDavid du Colombier convTR2M(Ticketreq *f, char *ap) 513*50a9bdd4SDavid du Colombier { 514*50a9bdd4SDavid du Colombier int n; 515*50a9bdd4SDavid du Colombier uchar *p; 516*50a9bdd4SDavid du Colombier 517*50a9bdd4SDavid du Colombier p = (uchar*)ap; 518*50a9bdd4SDavid du Colombier CHAR(type); 519*50a9bdd4SDavid du Colombier STRING(authid, NAMELEN); 520*50a9bdd4SDavid du Colombier STRING(authdom, DOMLEN); 521*50a9bdd4SDavid du Colombier STRING(chal, CHALLEN); 522*50a9bdd4SDavid du Colombier STRING(hostid, NAMELEN); 523*50a9bdd4SDavid du Colombier STRING(uid, NAMELEN); 524*50a9bdd4SDavid du Colombier n = p - (uchar*)ap; 525*50a9bdd4SDavid du Colombier return n; 526*50a9bdd4SDavid du Colombier } 527*50a9bdd4SDavid du Colombier 528*50a9bdd4SDavid du Colombier static int 529*50a9bdd4SDavid du Colombier convT2M(Ticket *f, char *ap, char *key) 530*50a9bdd4SDavid du Colombier { 531*50a9bdd4SDavid du Colombier int n; 532*50a9bdd4SDavid du Colombier uchar *p; 533*50a9bdd4SDavid du Colombier 534*50a9bdd4SDavid du Colombier p = (uchar*)ap; 535*50a9bdd4SDavid du Colombier CHAR(num); 536*50a9bdd4SDavid du Colombier STRING(chal, CHALLEN); 537*50a9bdd4SDavid du Colombier STRING(cuid, NAMELEN); 538*50a9bdd4SDavid du Colombier STRING(suid, NAMELEN); 539*50a9bdd4SDavid du Colombier STRING(key, DESKEYLEN); 540*50a9bdd4SDavid du Colombier n = p - (uchar*)ap; 541*50a9bdd4SDavid du Colombier if(key) 542*50a9bdd4SDavid du Colombier encrypt9p(key, ap, n); 543*50a9bdd4SDavid du Colombier return n; 544*50a9bdd4SDavid du Colombier } 545*50a9bdd4SDavid du Colombier 546*50a9bdd4SDavid du Colombier int 547*50a9bdd4SDavid du Colombier convA2M(Authenticator *f, char *ap, char *key) 548*50a9bdd4SDavid du Colombier { 549*50a9bdd4SDavid du Colombier int n; 550*50a9bdd4SDavid du Colombier uchar *p; 551*50a9bdd4SDavid du Colombier 552*50a9bdd4SDavid du Colombier p = (uchar*)ap; 553*50a9bdd4SDavid du Colombier CHAR(num); 554*50a9bdd4SDavid du Colombier STRING(chal, CHALLEN); 555*50a9bdd4SDavid du Colombier LONG(id); 556*50a9bdd4SDavid du Colombier n = p - (uchar*)ap; 557*50a9bdd4SDavid du Colombier if(key) 558*50a9bdd4SDavid du Colombier encrypt9p(key, ap, n); 559*50a9bdd4SDavid du Colombier return n; 560*50a9bdd4SDavid du Colombier } 561*50a9bdd4SDavid du Colombier 562*50a9bdd4SDavid du Colombier #undef CHAR 563*50a9bdd4SDavid du Colombier #undef SHORT 564*50a9bdd4SDavid du Colombier #undef VLONG 565*50a9bdd4SDavid du Colombier #undef LONG 566*50a9bdd4SDavid du Colombier #undef STRING 567*50a9bdd4SDavid du Colombier 568*50a9bdd4SDavid du Colombier #define CHAR(x) f->x = *p++ 569*50a9bdd4SDavid du Colombier #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 570*50a9bdd4SDavid du Colombier #define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 571*50a9bdd4SDavid du Colombier #define LONG(x) VLONG(f->x) 572*50a9bdd4SDavid du Colombier #define STRING(x,n) memmove(f->x, p, n); p += n 573*50a9bdd4SDavid du Colombier 574*50a9bdd4SDavid du Colombier void 575*50a9bdd4SDavid du Colombier convM2A(char *ap, Authenticator *f, char *key) 576*50a9bdd4SDavid du Colombier { 577*50a9bdd4SDavid du Colombier uchar *p; 578*50a9bdd4SDavid du Colombier 579*50a9bdd4SDavid du Colombier if(key) 580*50a9bdd4SDavid du Colombier decrypt9p(key, ap, AUTHENTLEN); 581*50a9bdd4SDavid du Colombier p = (uchar*)ap; 582*50a9bdd4SDavid du Colombier CHAR(num); 583*50a9bdd4SDavid du Colombier STRING(chal, CHALLEN); 584*50a9bdd4SDavid du Colombier LONG(id); 585*50a9bdd4SDavid du Colombier USED(p); 586*50a9bdd4SDavid du Colombier } 587*50a9bdd4SDavid du Colombier 588*50a9bdd4SDavid du Colombier void 589*50a9bdd4SDavid du Colombier convM2T(char *ap, Ticket *f, char *key) 590*50a9bdd4SDavid du Colombier { 591*50a9bdd4SDavid du Colombier uchar *p; 592*50a9bdd4SDavid du Colombier 593*50a9bdd4SDavid du Colombier if(key) 594*50a9bdd4SDavid du Colombier decrypt9p(key, ap, TICKETLEN); 595*50a9bdd4SDavid du Colombier p = (uchar*)ap; 596*50a9bdd4SDavid du Colombier CHAR(num); 597*50a9bdd4SDavid du Colombier STRING(chal, CHALLEN); 598*50a9bdd4SDavid du Colombier STRING(cuid, NAMELEN); 599*50a9bdd4SDavid du Colombier f->cuid[NAMELEN-1] = 0; 600*50a9bdd4SDavid du Colombier STRING(suid, NAMELEN); 601*50a9bdd4SDavid du Colombier f->suid[NAMELEN-1] = 0; 602*50a9bdd4SDavid du Colombier STRING(key, DESKEYLEN); 603*50a9bdd4SDavid du Colombier USED(p); 604*50a9bdd4SDavid du Colombier } 605*50a9bdd4SDavid du Colombier 606*50a9bdd4SDavid du Colombier #undef CHAR 607*50a9bdd4SDavid du Colombier #undef SHORT 608*50a9bdd4SDavid du Colombier #undef LONG 609*50a9bdd4SDavid du Colombier #undef VLONG 610*50a9bdd4SDavid du Colombier #undef STRING 611*50a9bdd4SDavid du Colombier 612*50a9bdd4SDavid du Colombier static int 613*50a9bdd4SDavid du Colombier passtokey(char *key, char *p) 614*50a9bdd4SDavid du Colombier { 615*50a9bdd4SDavid du Colombier uchar buf[NAMELEN], *t; 616*50a9bdd4SDavid du Colombier int i, n; 617*50a9bdd4SDavid du Colombier 618*50a9bdd4SDavid du Colombier n = strlen(p); 619*50a9bdd4SDavid du Colombier if(n >= NAMELEN) 620*50a9bdd4SDavid du Colombier n = NAMELEN-1; 621*50a9bdd4SDavid du Colombier memset(buf, ' ', 8); 622*50a9bdd4SDavid du Colombier t = buf; 623*50a9bdd4SDavid du Colombier strncpy((char*)t, p, n); 624*50a9bdd4SDavid du Colombier t[n] = 0; 625*50a9bdd4SDavid du Colombier memset(key, 0, DESKEYLEN); 626*50a9bdd4SDavid du Colombier for(;;){ 627*50a9bdd4SDavid du Colombier for(i = 0; i < DESKEYLEN; i++) 628*50a9bdd4SDavid du Colombier key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1))); 629*50a9bdd4SDavid du Colombier if(n <= 8) 630*50a9bdd4SDavid du Colombier return 1; 631*50a9bdd4SDavid du Colombier n -= 8; 632*50a9bdd4SDavid du Colombier t += 8; 633*50a9bdd4SDavid du Colombier if(n < 8){ 634*50a9bdd4SDavid du Colombier t -= 8 - n; 635*50a9bdd4SDavid du Colombier n = 8; 636*50a9bdd4SDavid du Colombier } 637*50a9bdd4SDavid du Colombier encrypt9p(key, t, 8); 638*50a9bdd4SDavid du Colombier } 639*50a9bdd4SDavid du Colombier return 1; /* not reached */ 640*50a9bdd4SDavid du Colombier } 641*50a9bdd4SDavid du Colombier 642*50a9bdd4SDavid du Colombier static char authkey[DESKEYLEN]; 643*50a9bdd4SDavid du Colombier static char *authid; 644*50a9bdd4SDavid du Colombier static char *authdom; 645*50a9bdd4SDavid du Colombier static char *haveprotosmsg; 646*50a9bdd4SDavid du Colombier static char *needprotomsg; 647*50a9bdd4SDavid du Colombier 648*50a9bdd4SDavid du Colombier static void 649*50a9bdd4SDavid du Colombier p9anyinit(void) 650*50a9bdd4SDavid du Colombier { 651*50a9bdd4SDavid du Colombier int n, fd; 652*50a9bdd4SDavid du Colombier char abuf[200]; 653*50a9bdd4SDavid du Colombier char *af, *f[4]; 654*50a9bdd4SDavid du Colombier 655*50a9bdd4SDavid du Colombier af = autharg; 656*50a9bdd4SDavid du Colombier if(af == nil) 657*50a9bdd4SDavid du Colombier af = "/etc/u9fs.key"; 658*50a9bdd4SDavid du Colombier 659*50a9bdd4SDavid du Colombier if((fd = open(af, OREAD)) < 0) 660*50a9bdd4SDavid du Colombier sysfatal("can't open key file '%s'", af); 661*50a9bdd4SDavid du Colombier 662*50a9bdd4SDavid du Colombier if((n = readn(fd, abuf, sizeof(abuf)-1)) < 0) 663*50a9bdd4SDavid du Colombier sysfatal("can't read key file '%s'", af); 664*50a9bdd4SDavid du Colombier if (n > 0 && abuf[n - 1] == '\n') 665*50a9bdd4SDavid du Colombier n--; 666*50a9bdd4SDavid du Colombier abuf[n] = '\0'; 667*50a9bdd4SDavid du Colombier 668*50a9bdd4SDavid du Colombier if(getfields(abuf, f, nelem(f), 0, "\n") != 3) 669*50a9bdd4SDavid du Colombier sysfatal("key file '%s' not exactly 3 lines", af); 670*50a9bdd4SDavid du Colombier 671*50a9bdd4SDavid du Colombier passtokey(authkey, f[0]); 672*50a9bdd4SDavid du Colombier authid = strdup(f[1]); 673*50a9bdd4SDavid du Colombier authdom = strdup(f[2]); 674*50a9bdd4SDavid du Colombier haveprotosmsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1); 675*50a9bdd4SDavid du Colombier sprint(haveprotosmsg, "p9sk1@%s", authdom); 676*50a9bdd4SDavid du Colombier needprotomsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1); 677*50a9bdd4SDavid du Colombier sprint(needprotomsg, "p9sk1 %s", authdom); 678*50a9bdd4SDavid du Colombier } 679*50a9bdd4SDavid du Colombier 680*50a9bdd4SDavid du Colombier typedef struct AuthSession { 681*50a9bdd4SDavid du Colombier int state; 682*50a9bdd4SDavid du Colombier char *uname; 683*50a9bdd4SDavid du Colombier char *aname; 684*50a9bdd4SDavid du Colombier char cchal[CHALLEN]; 685*50a9bdd4SDavid du Colombier Ticketreq tr; 686*50a9bdd4SDavid du Colombier Ticket t; 687*50a9bdd4SDavid du Colombier } AuthSession; 688*50a9bdd4SDavid du Colombier 689*50a9bdd4SDavid du Colombier static char* 690*50a9bdd4SDavid du Colombier p9anyauth(Fcall *rx, Fcall *tx) 691*50a9bdd4SDavid du Colombier { 692*50a9bdd4SDavid du Colombier AuthSession *sp; 693*50a9bdd4SDavid du Colombier int result; 694*50a9bdd4SDavid du Colombier Fid *f; 695*50a9bdd4SDavid du Colombier char *ep; 696*50a9bdd4SDavid du Colombier 697*50a9bdd4SDavid du Colombier sp = malloc(sizeof(AuthSession)); 698*50a9bdd4SDavid du Colombier f = newauthfid(rx->afid, sp, &ep); 699*50a9bdd4SDavid du Colombier if (f == nil) { 700*50a9bdd4SDavid du Colombier free(sp); 701*50a9bdd4SDavid du Colombier return ep; 702*50a9bdd4SDavid du Colombier } 703*50a9bdd4SDavid du Colombier if (chatty9p) 704*50a9bdd4SDavid du Colombier fprint(2, "p9anyauth: afid %d\n", rx->afid); 705*50a9bdd4SDavid du Colombier sp->state = HaveProtos; 706*50a9bdd4SDavid du Colombier sp->uname = strdup(rx->uname); 707*50a9bdd4SDavid du Colombier sp->aname = strdup(rx->aname); 708*50a9bdd4SDavid du Colombier tx->aqid.type = QTAUTH; 709*50a9bdd4SDavid du Colombier tx->aqid.path = 1; 710*50a9bdd4SDavid du Colombier tx->aqid.vers = 0; 711*50a9bdd4SDavid du Colombier return nil; 712*50a9bdd4SDavid du Colombier } 713*50a9bdd4SDavid du Colombier 714*50a9bdd4SDavid du Colombier static char * 715*50a9bdd4SDavid du Colombier p9anyattach(Fcall *rx, Fcall *tx) 716*50a9bdd4SDavid du Colombier { 717*50a9bdd4SDavid du Colombier AuthSession *sp; 718*50a9bdd4SDavid du Colombier Fid *f; 719*50a9bdd4SDavid du Colombier char *ep; 720*50a9bdd4SDavid du Colombier 721*50a9bdd4SDavid du Colombier f = oldauthfid(rx->afid, (void **)&sp, &ep); 722*50a9bdd4SDavid du Colombier if (f == nil) 723*50a9bdd4SDavid du Colombier return ep; 724*50a9bdd4SDavid du Colombier if (chatty9p) 725*50a9bdd4SDavid du Colombier fprint(2, "p9anyattach: afid %d state %d\n", rx->afid, sp->state); 726*50a9bdd4SDavid du Colombier if (sp->state == Established && strcmp(rx->uname, sp->uname) == 0 727*50a9bdd4SDavid du Colombier && strcmp(rx->aname, sp->aname) == 0) 728*50a9bdd4SDavid du Colombier return nil; 729*50a9bdd4SDavid du Colombier return "authentication failed"; 730*50a9bdd4SDavid du Colombier } 731*50a9bdd4SDavid du Colombier 732*50a9bdd4SDavid du Colombier static int 733*50a9bdd4SDavid du Colombier readstr(Fcall *rx, Fcall *tx, char *s, int len) 734*50a9bdd4SDavid du Colombier { 735*50a9bdd4SDavid du Colombier if (rx->offset >= len) 736*50a9bdd4SDavid du Colombier return 0; 737*50a9bdd4SDavid du Colombier tx->count = len - rx->offset; 738*50a9bdd4SDavid du Colombier if (tx->count > rx->count) 739*50a9bdd4SDavid du Colombier tx->count = rx->count; 740*50a9bdd4SDavid du Colombier memcpy(tx->data, s + rx->offset, tx->count); 741*50a9bdd4SDavid du Colombier return tx->count; 742*50a9bdd4SDavid du Colombier } 743*50a9bdd4SDavid du Colombier 744*50a9bdd4SDavid du Colombier static char * 745*50a9bdd4SDavid du Colombier p9anyread(Fcall *rx, Fcall *tx) 746*50a9bdd4SDavid du Colombier { 747*50a9bdd4SDavid du Colombier AuthSession *sp; 748*50a9bdd4SDavid du Colombier char *ep; 749*50a9bdd4SDavid du Colombier char buf[100]; 750*50a9bdd4SDavid du Colombier 751*50a9bdd4SDavid du Colombier Fid *f; 752*50a9bdd4SDavid du Colombier f = oldauthfid(rx->afid, (void **)&sp, &ep); 753*50a9bdd4SDavid du Colombier if (f == nil) 754*50a9bdd4SDavid du Colombier return ep; 755*50a9bdd4SDavid du Colombier if (chatty9p) 756*50a9bdd4SDavid du Colombier fprint(2, "p9anyread: afid %d state %d\n", rx->fid, sp->state); 757*50a9bdd4SDavid du Colombier switch (sp->state) { 758*50a9bdd4SDavid du Colombier case HaveProtos: 759*50a9bdd4SDavid du Colombier readstr(rx, tx, haveprotosmsg, strlen(haveprotosmsg) + 1); 760*50a9bdd4SDavid du Colombier if (rx->offset + tx->count == strlen(haveprotosmsg) + 1) 761*50a9bdd4SDavid du Colombier sp->state = NeedProto; 762*50a9bdd4SDavid du Colombier return nil; 763*50a9bdd4SDavid du Colombier case HaveTreq: 764*50a9bdd4SDavid du Colombier if (rx->count != TICKREQLEN) 765*50a9bdd4SDavid du Colombier goto botch; 766*50a9bdd4SDavid du Colombier convTR2M(&sp->tr, tx->data); 767*50a9bdd4SDavid du Colombier tx->count = TICKREQLEN; 768*50a9bdd4SDavid du Colombier sp->state = NeedTicket; 769*50a9bdd4SDavid du Colombier return nil; 770*50a9bdd4SDavid du Colombier case HaveAuth: { 771*50a9bdd4SDavid du Colombier Authenticator a; 772*50a9bdd4SDavid du Colombier if (rx->count != AUTHENTLEN) 773*50a9bdd4SDavid du Colombier goto botch; 774*50a9bdd4SDavid du Colombier a.num = AuthAs; 775*50a9bdd4SDavid du Colombier memmove(a.chal, sp->cchal, CHALLEN); 776*50a9bdd4SDavid du Colombier a.id = 0; 777*50a9bdd4SDavid du Colombier convA2M(&a, (char*)tx->data, sp->t.key); 778*50a9bdd4SDavid du Colombier memset(sp->t.key, 0, sizeof(sp->t.key)); 779*50a9bdd4SDavid du Colombier tx->count = rx->count; 780*50a9bdd4SDavid du Colombier sp->state = Established; 781*50a9bdd4SDavid du Colombier return nil; 782*50a9bdd4SDavid du Colombier } 783*50a9bdd4SDavid du Colombier default: 784*50a9bdd4SDavid du Colombier botch: 785*50a9bdd4SDavid du Colombier return "protocol botch"; 786*50a9bdd4SDavid du Colombier } 787*50a9bdd4SDavid du Colombier } 788*50a9bdd4SDavid du Colombier 789*50a9bdd4SDavid du Colombier static char * 790*50a9bdd4SDavid du Colombier p9anywrite(Fcall *rx, Fcall *tx) 791*50a9bdd4SDavid du Colombier { 792*50a9bdd4SDavid du Colombier AuthSession *sp; 793*50a9bdd4SDavid du Colombier char *ep; 794*50a9bdd4SDavid du Colombier 795*50a9bdd4SDavid du Colombier Fid *f; 796*50a9bdd4SDavid du Colombier 797*50a9bdd4SDavid du Colombier f = oldauthfid(rx->afid, (void **)&sp, &ep); 798*50a9bdd4SDavid du Colombier if (f == nil) 799*50a9bdd4SDavid du Colombier return ep; 800*50a9bdd4SDavid du Colombier if (chatty9p) 801*50a9bdd4SDavid du Colombier fprint(2, "p9anywrite: afid %d state %d\n", rx->fid, sp->state); 802*50a9bdd4SDavid du Colombier switch (sp->state) { 803*50a9bdd4SDavid du Colombier case NeedProto: 804*50a9bdd4SDavid du Colombier if (rx->count != strlen(needprotomsg) + 1) 805*50a9bdd4SDavid du Colombier return "protocol response wrong length"; 806*50a9bdd4SDavid du Colombier if (memcmp(rx->data, needprotomsg, rx->count) != 0) 807*50a9bdd4SDavid du Colombier return "unacceptable protocol"; 808*50a9bdd4SDavid du Colombier sp->state = NeedChal; 809*50a9bdd4SDavid du Colombier tx->count = rx->count; 810*50a9bdd4SDavid du Colombier return nil; 811*50a9bdd4SDavid du Colombier case NeedChal: 812*50a9bdd4SDavid du Colombier if (rx->count != CHALLEN) 813*50a9bdd4SDavid du Colombier goto botch; 814*50a9bdd4SDavid du Colombier memmove(sp->cchal, rx->data, CHALLEN); 815*50a9bdd4SDavid du Colombier sp->tr.type = AuthTreq; 816*50a9bdd4SDavid du Colombier safecpy(sp->tr.authid, authid, sizeof(sp->tr.authid)); 817*50a9bdd4SDavid du Colombier safecpy(sp->tr.authdom, authdom, sizeof(sp->tr.authdom)); 818*50a9bdd4SDavid du Colombier randombytes((uchar *)sp->tr.chal, CHALLEN); 819*50a9bdd4SDavid du Colombier safecpy(sp->tr.hostid, "", sizeof(sp->tr.hostid)); 820*50a9bdd4SDavid du Colombier safecpy(sp->tr.uid, "", sizeof(sp->tr.uid)); 821*50a9bdd4SDavid du Colombier tx->count = rx->count; 822*50a9bdd4SDavid du Colombier sp->state = HaveTreq; 823*50a9bdd4SDavid du Colombier return nil; 824*50a9bdd4SDavid du Colombier case NeedTicket: { 825*50a9bdd4SDavid du Colombier Authenticator a; 826*50a9bdd4SDavid du Colombier 827*50a9bdd4SDavid du Colombier if (rx->count != TICKETLEN + AUTHENTLEN) { 828*50a9bdd4SDavid du Colombier fprint(2, "bad length in attach"); 829*50a9bdd4SDavid du Colombier goto botch; 830*50a9bdd4SDavid du Colombier } 831*50a9bdd4SDavid du Colombier convM2T((char*)rx->data, &sp->t, authkey); 832*50a9bdd4SDavid du Colombier if (sp->t.num != AuthTs) { 833*50a9bdd4SDavid du Colombier fprint(2, "bad AuthTs in attach\n"); 834*50a9bdd4SDavid du Colombier goto botch; 835*50a9bdd4SDavid du Colombier } 836*50a9bdd4SDavid du Colombier if (memcmp(sp->t.chal, sp->tr.chal, CHALLEN) != 0) { 837*50a9bdd4SDavid du Colombier fprint(2, "bad challenge in attach\n"); 838*50a9bdd4SDavid du Colombier goto botch; 839*50a9bdd4SDavid du Colombier } 840*50a9bdd4SDavid du Colombier convM2A((char*)rx->data + TICKETLEN, &a, sp->t.key); 841*50a9bdd4SDavid du Colombier if (a.num != AuthAc) { 842*50a9bdd4SDavid du Colombier fprint(2, "bad AuthAs in attach\n"); 843*50a9bdd4SDavid du Colombier goto botch; 844*50a9bdd4SDavid du Colombier } 845*50a9bdd4SDavid du Colombier if(memcmp(a.chal, sp->tr.chal, CHALLEN) != 0) { 846*50a9bdd4SDavid du Colombier fprint(2, "bad challenge in attach 2\n"); 847*50a9bdd4SDavid du Colombier goto botch; 848*50a9bdd4SDavid du Colombier } 849*50a9bdd4SDavid du Colombier sp->state = HaveAuth; 850*50a9bdd4SDavid du Colombier tx->count = rx->count; 851*50a9bdd4SDavid du Colombier return nil; 852*50a9bdd4SDavid du Colombier } 853*50a9bdd4SDavid du Colombier default: 854*50a9bdd4SDavid du Colombier botch: 855*50a9bdd4SDavid du Colombier return "protocol botch"; 856*50a9bdd4SDavid du Colombier } 857*50a9bdd4SDavid du Colombier } 858*50a9bdd4SDavid du Colombier 859*50a9bdd4SDavid du Colombier static void 860*50a9bdd4SDavid du Colombier safefree(char *p) 861*50a9bdd4SDavid du Colombier { 862*50a9bdd4SDavid du Colombier if (p) { 863*50a9bdd4SDavid du Colombier memset(p, 0, strlen(p)); 864*50a9bdd4SDavid du Colombier free(p); 865*50a9bdd4SDavid du Colombier } 866*50a9bdd4SDavid du Colombier } 867*50a9bdd4SDavid du Colombier 868*50a9bdd4SDavid du Colombier static char * 869*50a9bdd4SDavid du Colombier p9anyclunk(Fcall *rx, Fcall *tx) 870*50a9bdd4SDavid du Colombier { 871*50a9bdd4SDavid du Colombier Fid *f; 872*50a9bdd4SDavid du Colombier AuthSession *sp; 873*50a9bdd4SDavid du Colombier char *ep; 874*50a9bdd4SDavid du Colombier 875*50a9bdd4SDavid du Colombier f = oldauthfid(rx->afid, (void **)&sp, &ep); 876*50a9bdd4SDavid du Colombier if (f == nil) 877*50a9bdd4SDavid du Colombier return ep; 878*50a9bdd4SDavid du Colombier if (chatty9p) 879*50a9bdd4SDavid du Colombier fprint(2, "p9anyclunk: afid %d\n", rx->fid); 880*50a9bdd4SDavid du Colombier safefree(sp->uname); 881*50a9bdd4SDavid du Colombier safefree(sp->aname); 882*50a9bdd4SDavid du Colombier memset(sp, 0, sizeof(sp)); 883*50a9bdd4SDavid du Colombier free(sp); 884*50a9bdd4SDavid du Colombier return nil; 885*50a9bdd4SDavid du Colombier } 886*50a9bdd4SDavid du Colombier 887*50a9bdd4SDavid du Colombier Auth authp9any = { 888*50a9bdd4SDavid du Colombier "p9any", 889*50a9bdd4SDavid du Colombier p9anyauth, 890*50a9bdd4SDavid du Colombier p9anyattach, 891*50a9bdd4SDavid du Colombier p9anyinit, 892*50a9bdd4SDavid du Colombier p9anyread, 893*50a9bdd4SDavid du Colombier p9anywrite, 894*50a9bdd4SDavid du Colombier p9anyclunk, 895*50a9bdd4SDavid du Colombier }; 896