/* NetWare Encrypted Password Test Code Compiled by Fauzan Mirza, June 1994 Original source put together by Willem Jan Hengeveld encryptp : create encrypted password from userid, and password getpassk : create login data from encrypted password & logkey encrypt3 : create change pw date from login data for old pw + encrypted new pw */ #include #include #include #include #include #define MAXPWLEN 128 #define MAXNAMELEN 48 typedef unsigned char BYTE; BYTE tab0[256]= /* used by encrypt */ {/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 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 }; BYTE tab[32]= /* used by encrypt & encryptp */ { 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 }; BYTE tab1[8][2][16]= /* used by encrypt3 */ { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ {{ 0xF,0x8,0x5,0x7,0xC,0x2,0xE,0x9,0x0,0x1,0x6,0xD,0x3,0x4,0xB,0xA}, { 0x2,0xC,0xE,0x6,0xF,0x0,0x1,0x8,0xD,0x3,0xA,0x4,0x9,0xB,0x5,0x7}}, {{ 0x5,0x2,0x9,0xF,0xC,0x4,0xD,0x0,0xE,0xA,0x6,0x8,0xB,0x1,0x3,0x7}, { 0xF,0xD,0x2,0x6,0x7,0x8,0x5,0x9,0x0,0x4,0xC,0x3,0x1,0xA,0xB,0xE}}, {{ 0x5,0xE,0x2,0xB,0xD,0xA,0x7,0x0,0x8,0x6,0x4,0x1,0xF,0xC,0x3,0x9}, { 0x8,0x2,0xF,0xA,0x5,0x9,0x6,0xC,0x0,0xB,0x1,0xD,0x7,0x3,0x4,0xE}}, {{ 0xE,0x8,0x0,0x9,0x4,0xB,0x2,0x7,0xC,0x3,0xA,0x5,0xD,0x1,0x6,0xF}, { 0x1,0x4,0x8,0xA,0xD,0xB,0x7,0xE,0x5,0xF,0x3,0x9,0x0,0x2,0x6,0xC}}, {{ 0x5,0x3,0xC,0x8,0xB,0x2,0xE,0xA,0x4,0x1,0xD,0x0,0x6,0x7,0xF,0x9}, { 0x6,0x0,0xB,0xE,0xD,0x4,0xC,0xF,0x7,0x2,0x8,0xA,0x1,0x5,0x3,0x9}}, {{ 0xB,0x5,0xA,0xE,0xF,0x1,0xC,0x0,0x6,0x4,0x2,0x9,0x3,0xD,0x7,0x8}, { 0x7,0x2,0xA,0x0,0xE,0x8,0xF,0x4,0xC,0xB,0x9,0x1,0x5,0xD,0x3,0x6}}, {{ 0x7,0x4,0xF,0x9,0x5,0x1,0xC,0xB,0x0,0x3,0x8,0xE,0x2,0xA,0x6,0xD}, { 0x9,0x4,0x8,0x0,0xA,0x3,0x1,0xC,0x5,0xF,0x7,0x2,0xB,0xE,0x6,0xD}}, {{ 0x9,0x5,0x4,0x7,0xE,0x8,0x3,0x1,0xD,0xB,0xC,0x2,0x0,0xF,0x6,0xA}, { 0x9,0xA,0xB,0xD,0x5,0x3,0xF,0x0,0x1,0xC,0x8,0x7,0x6,0x4,0xE,0x2}} }; BYTE tab3[16]= /* used by encrypt3 */ { 0x3,0xE,0xF,0x2,0xD,0xC,0x4,0x5,0x9,0x6,0x0,0x1,0xB,0x7,0xA,0x8 }; /* debugging functions */ void dump(BYTE *p,int l) { int i; for (i=0 ; i=32 ; len-=32) for (i=0 ; i<32 ; q++, i++) buf[i] ^= *q; p=q; if (len>0) for (i=0 ; i<32 ; i++) { if (q+len==p) { p=q; buf[i]^=tab[i]; } else buf[i]^=*p++; } for (i=0 ; i<32 ; i++) buf[i] ^= ((BYTE *)&id)[i&3]; encrypt(buf,dst); } /* char logkey[8] : (requested with int21,ax=e3, fn 17 from server) * char crpw[16] : encrypted password (with encryptp) * char dst[8] : login data (result) */ void getpassk(long *logkey, BYTE *crpw, BYTE *dst) { BYTE buf[32]; int i,j; encryptp(logkey[0],crpw,16,buf); encryptp(logkey[1],crpw,16,buf+16); for (i=0, j=31 ; i<16 ; i++, j--) buf[i]^=buf[j]; for (i=0 , j=15 ; i<8 ; i++, j--) dst[i]=buf[i]^buf[j]; } /* char p1[8] : part of old encrypted pw * char p2[8] : part of new encrypted pw * char p3[8] : part of change pw data (result) */ void encrypt3(register BYTE *p1, BYTE *p2, BYTE *p3) { register int j; BYTE c; BYTE buf[8]; int i; memcpy(buf,p2,8); for (i=0 ; i<16 ; i++) { for (j=0 ; j<8 ; j++) { c=buf[j]^p1[j]; buf[j]= tab1[j][0][c&15] | (tab1[j][1][c>>4] <<4); } c=p1[7]; for (j=7 ; j>0 ; j--) p1[j]=(p1[j]<<4) | (p1[j-1]>>4); p1[0]= (c>>4) | (p1[0]<<4); memset(p3,0,8); for (j=0 ; j<16 ; j++) { c= tab3[j]; c= (tab3[j]&1) ? (buf[c/2]>>4) : (buf[c/2]&0xf) ; p3[j/2] |= (j&1) ? (c<<4) : c ; } memcpy(buf,p3,8); } } int shreq(int f, BYTE *req, int rl, BYTE *ans, int al) { struct REGPACK r; r.r_cx=rl; r.r_dx=al; r.r_si=FP_OFF(req); r.r_di=FP_OFF(ans); r.r_ds=FP_SEG(req); r.r_es=FP_SEG(ans); r.r_ax=0xf200|f; intr(0x21,&r); return(r.r_ax&0xff); } /* get encryption key */ int getlogkey(BYTE *s) { BYTE req[3]; req[0]=0; req[1]=1; req[2]=0x17; return(shreq(0x17,req,3,s,8)); } int getobjid(char *name, int type, long *id) { BYTE req[MAXNAMELEN+6]; BYTE rep[MAXNAMELEN+6]; int err; req[2]=0x35; *(int *)(req+3)=type; req[5]=strlen(name); strncpy((char *)req+6,name,MAXNAMELEN); req[0]=0; req[1]=req[5]+4; err=shreq(0x17,req,req[1]+2,rep,MAXNAMELEN+6); *id=*(long *)rep; return(err); } int setpwcrypt(BYTE *oldpw, int type, char *name, BYTE *newpw, int l) { BYTE req[MAXNAMELEN+31]; /* 8+16(pw's) + 1 + 3(type+len) + 3(header) */ req[2]=0x4b; memcpy(req+3,oldpw,8); *(int *)(req+11)=type; req[13]=strlen(name); strncpy((char *)req+14,name,48); req[14+req[13]]=l; memcpy(req+15+req[13],newpw,16); req[0]=0; req[1]=29+req[13]; return(shreq(0x17,req,req[1]+2,req,0)); } int setpw(char *name, int type, char *oldpw, char *newpw) { BYTE req[8+MAXNAMELEN+2*MAXPWLEN]; int l=5; req[2]=0x40; *(int *)(req+3)=type; req[l++]=strlen(name); strncpy((char *)req+l,name,MAXNAMELEN); l+=req[l]; req[l++]=strlen(newpw); strncpy((char *)req+l,newpw,MAXPWLEN); l+=req[l]; req[l++]=strlen(oldpw); strncpy((char *)req+l,oldpw,MAXPWLEN); l+=req[l]; req[0]=l>>8; req[1]=l&0xff; return(shreq(0x17,req,l+2,req,0)); } int changepw(char *name, int type, char *oldpw, char *newpw) { BYTE logkey[8]; long id; BYTE oldcrpw[16]; BYTE newcrpw[16]; int err; int l; if (getlogkey(logkey)==0) { err=getobjid(name,type,&id); if (err) return (err); encryptp(id,(BYTE *)oldpw,strlen(oldpw),oldcrpw); encryptp(id,(BYTE *)newpw,strlen(newpw),newcrpw); getpassk((long *)logkey,oldcrpw,logkey); encrypt3(oldcrpw,newcrpw,newcrpw); encrypt3(oldcrpw+8,newcrpw+8,newcrpw+8); l=((( min(63,strlen(newpw))^oldcrpw[0]^oldcrpw[1] )&0x7f)|0x40); return(setpwcrypt(logkey,type,name,newcrpw,l)); } else return(setpw(name,type,oldpw,newpw)); } int trypw(char *pw, int type, char *name) { BYTE req[7+MAXNAMELEN+MAXPWLEN]; req[2]=0x3f; *(int *)(req+3)=type; req[5]=strlen(name); strncpy((char *)req+6,name,MAXNAMELEN); req[6+req[5]]=strlen(pw); strncpy((char *)req+7+req[5],pw,MAXPWLEN); req[0]=0; req[1]=5+req[5]+req[6+req[5]]; return(shreq(0x17,req,req[1]+2,req,0)); } int trypwcrypt(BYTE *crpw, int type, char *name) { BYTE req[14+MAXNAMELEN]; req[2]=0x4a; memcpy(req+3,crpw,8); *(int *)(req+11)=type; req[13]=strlen(name); strncpy((char *)req+14,name,MAXNAMELEN); req[0]=0; req[1]=12+req[13]; return(shreq(0x17,req,req[1]+2,req,0)); } int testpw(char *name, int type, char *pw) { BYTE logkey[8], crpw[16]; long id; int err; if (getlogkey(logkey)==0) { printf("Encryption Key: "); dump(logkey,8); err=getobjid(name,type,&id); if (err) return (err); printf("Object ID: %lX\n",swap(id)); encryptp(id,(BYTE *)pw,strlen(pw),crpw); printf("Encrypted Password: "); dump(crpw,16); getpassk((long *)logkey,crpw,logkey); printf("Result Login Key: "); dump(logkey,8); return(trypwcrypt(logkey,type,name)); } else { puts("Failed to get logkey"); return(trypw(name,type,pw)); } } int logincrypt(BYTE *crpw, int type, char *name) { BYTE req[14+MAXNAMELEN]; req[2]=0x18; memcpy(req+3,crpw,8); *(int *)(req+11)=type; req[13]=strlen(name); strncpy((char *)req+14,name,MAXNAMELEN); req[0]=0; req[1]=12+req[13]; return(shreq(0x17,req,req[1]+2,req,0)); } int login(char *name, int type, char *pw) { BYTE req[7+MAXNAMELEN+MAXPWLEN]; req[2]=0x14; *(int *)(req+3)=type; req[5]=strlen(name); strncpy((char *)req+6,name,MAXNAMELEN); req[6+req[5]]=strlen(pw); strncpy((char *)req+7+req[5],pw,MAXPWLEN); req[0]=0; req[1]=5+req[5]+req[6+req[5]]; return(shreq(0x17,req,req[1]+2,req,0)); } int dologin(char *name, int type, char *pw) { BYTE logkey[8]; long id; BYTE crpw[16]; int err; if (getlogkey(logkey)==0) { err=getobjid(name,type,&id); if (err) return (err); encryptp(id,(BYTE *)pw,strlen(pw),crpw); getpassk((long *)logkey,crpw,logkey); return(logincrypt(logkey,type,name)); } else return(login(name,type,pw)); } void main(int argc, char **argv) { char pw[MAXPWLEN]; char newpw[MAXPWLEN]; int err; int i; if (argc<3){ puts("Usage : NPASS "); puts(" := TEST | CHANGE | LOGIN"); exit(1); } strupr(argv[2]); while (kbhit()) getch(); switch(argv[1][0]) { case 'T': case 't': /* VerifyBinderyObjectPassword */ printf("Verify Password: "); gets(pw); err=testpw(argv[2],0x100,pw); printf("Result: %02X\n",err); break; case 'C': case 'c': /* ChangeBinderyObjectPassword */ printf("Enter Old Password: "); gets(pw); printf("Enter New Password: "); gets(newpw); err=changepw(argv[2],0x100,pw,newpw); printf("Result: %02X\n",err); break; case 'L': case 'l': /* LoginEncryptedObject */ printf("Login Password: "); gets(pw); err=dologin(argv[2],0x100,pw); printf("Result: %02X\n",err); break; default: puts("Unknown pwfunction parameter"); } }