/* * This is a simple DES encryption/decryption program that uses CDSA. * It's compatible with Eric A. Young's des program, which is included * in OpenSSL. */ /* * OpenVMS History * * 04-Dec-2002 Carol Kelly * * This version has been modified for OpenVMS to use rms file * processing to preserve the file attributes. */ #include #include #include #include #include #define _NEW_STARLET 1 #include #define VMS_Success 1 #define VMS_Failure 0 extern int DoDes(const char *, int, int, struct RAB *inrab, struct RAB *outrab); extern _init(); static void Usage() { int i; static const char *msg[]={ "des -e|d [input-file [output-file]]", "options:", "-e : encrypt using sunOS compatible user key to DES key conversion.", "-d : decrypt using sunOS compatible user key to DES key conversion.", "-h : the key that is entered will be a hexadecimal number", " that is used directly as the des key", "-k key : use key 'key'", NULL }; for (i = 0; msg[i]; i++) fprintf(stderr, "%s\n", msg[i]); } static void SetOddParity(char *key, int keyLen) { int i, c, numBitsSet; for (i = 0; i < keyLen; i++) { numBitsSet = 0; for (c = key[i] & 0x7f; c; c >>= 1) if (c & 1) numBitsSet++; if (numBitsSet & 1) key[i] &= 0x7f; else key[i] |= 0x80; } } static int HexStrToKey(char *key, int keyLen, const char *s) { const char *p = s; char buf[3], *endptr; int i; if (strlen(p) != (keyLen * 2)) return -1; buf[2] = '\0'; for (i = 0; i < keyLen; i++) { buf[0] = *p++; buf[1] = *p++; key[i] = strtol(buf, &endptr, 16); if (endptr != &buf[2]) return -1; } return 0; } static int StrToKey(char *key, int keyLen, const char *s) { bzero(key, keyLen); strncpy(key, s, keyLen); SetOddParity(key, keyLen); return 0; } int main(int argc, char *argv[]) { int o, doDecrypt = 0, doEncrypt = 0, hexFlag = 0; char *keyArg = NULL, key[8]; int status, ret_status; struct FAB infab, outfab, *fab; struct RAB inrab, outrab, *rab; struct XABFHC inxabfhc, outxabfhc; /* xab with file header characteristics */ while ((o = getopt(argc, argv, "dehk:")) != EOF) { switch (o) { case 'd': doDecrypt++; break; case 'e': doEncrypt++; break; case 'h': hexFlag++; break; case 'k': keyArg = strdup(optarg); memset(optarg, 0, strlen(optarg)); break; default: Usage(); exit(1); } } argc -= optind; argv += optind; if (!(doDecrypt ^ doEncrypt) || !keyArg || (argc > 2)) { Usage(); exit(VMS_Failure); } if ((hexFlag ? HexStrToKey : StrToKey)(key, sizeof key, keyArg)) { fprintf(stderr, "des: bad key: %s\n", keyArg); exit(VMS_Failure); } /* ** Set up a FAB to open the input file. */ infab = cc$rms_fab; infab.fab$l_fna = argv[0]; infab.fab$b_fns = strlen(argv[0]); infab.fab$v_bio = 1; /* for block i/o */ infab.fab$v_get = 1; /* for block i/o */ inxabfhc = cc$rms_xabfhc; infab.fab$l_xab = &inxabfhc; status = sys$open( &infab ); if( infab.fab$l_sts != RMS$_NORMAL){ printf( "Open failed: return status %X, rms status %X\n", status, infab.fab$l_sts ); exit( infab.fab$l_sts ); } inrab = cc$rms_rab; inrab.rab$l_fab = &infab; status = sys$connect( &inrab ); if( inrab.rab$l_sts != RMS$_NORMAL){ printf( "Connect failed: return status %X, rms status %X\n", status, inrab.rab$l_sts ); exit( inrab.rab$l_sts ); } /* ** Set up a FAB to create the output file. */ outfab = cc$rms_fab; outfab.fab$l_fna = argv[1]; outfab.fab$b_fns = strlen(argv[1]); outfab.fab$v_bio = 1; /* for block i/o */ outfab.fab$v_get = 1; /* for block i/o */ /* ** Collect file attributes from input FAB to pass onto output file. */ outfab.fab$b_org = infab.fab$b_org; outfab.fab$b_rat = infab.fab$b_rat; outfab.fab$b_rfm = infab.fab$b_rfm; outfab.fab$w_mrs = infab.fab$w_mrs; outfab.fab$l_mrn = infab.fab$l_mrn; outxabfhc = cc$rms_xabfhc; outfab.fab$l_xab = &outxabfhc; outxabfhc.xab$w_lrl = inxabfhc.xab$w_lrl; status = RMS$_NORMAL; status = sys$create( &outfab ); if( outfab.fab$l_sts != RMS$_NORMAL){ printf( "Create failed: return status %X, rms status %X\n", status, outfab.fab$l_sts ); exit( outfab.fab$l_sts ); } outrab = cc$rms_rab; outrab.rab$l_fab = &outfab; outrab.rab$b_rac = inrab.rab$b_rac; status = sys$connect( &outrab ); if( outrab.rab$l_sts != RMS$_NORMAL){ printf( "Connect failed: return status %X, rms status %X\n", status, outrab.rab$l_sts ); exit( outrab.rab$l_sts ); } _init(); ret_status = DoDes(key, sizeof key, doEncrypt, &inrab, &outrab); status = sys$close( &infab ); status = sys$close( &outfab ); if( !(ret_status & 1) ) exit(ret_status); if( !(status & 1) ) exit(status); exit(VMS_Success); }