The following is come code I found I wrote many years ago in Digital VAX MACRO to check passwords for a particular username against a dictionary of words concatenated with a number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | .title check_password $rmsdef $uaidef .psect rw_data rd,wrt,noexe,noshr, long pwdlist_fab: $fab fnm = <sys$library:VMS$PASSWORD_DICTIONARY.DATA> pwdlist_rab: $rab fab = pwdlist_fab,- rop = rah,- ubf = rec_buff,- usz = rec_size rec_size = 32 rec_desc: .word rec_size .word 0 .address rec_buff rec_buff: .blkb rec_size cur_count: . long max_count = 99 num_size = 2 cur_no: .ascid \99\ cur_pwd: .word rec_size+num_size .word 0 .address 10$ 10$: .blkb rec_size+num_size cur_hash: .blkb 8 username: username_len: .word 12 .word 0 .address 10$ 10$: .blkb 12 pwd_list: .word 1 .word uai$_encrypt .address encrypt .address encrypt_len .word 8 .word uai$_pwd .address pwd .address pwd_len .word 2 .word uai$_salt .address salt .address salt_len .word 0 .word 0 encrypt: .byte encrypt_len: .word pwd: .blkb 8 pwd_len: .word salt: .word salt_len: .word usage_msg: .ascid \VMS username must be specificed as a parameter\ .psect code rd,nowrt,exe,shr, long .entry check_password,^m<> ; get username passed on command line - display error if not present pushaq username calls #1,g^lib$get_foreign blbc r0,error_exit pushaw username_len pushaq username pushaq username calls #3,g^str$trim blbc r0,error_exit tstw username_len bnequ get_pwd pushaq usage_msg calls #1,g^lib$put_output brb normal_exit ; retrieve the hashed password from the UAF file get_pwd: $getuai_s usrnam=username,- itmlst=pwd_list blbc r0,error_exit ; open the VMS password dictionary open_dic: $open fab=pwdlist_fab blbc r0,error_exit $connect rab=pwdlist_rab blbc r0,error_exit ; retrieve a word from the dictionary word_loop: $get rab=pwdlist_rab blbs r0,remove_nulls cmpl r0,#rms$_eof beql normal_exit brb error_exit ; get rid of nulls on the end of the record and convert to uppercase remove_nulls: clrw r1 movaq rec_buff,r2 10$: tstb (r2) beql 20$ incw r1 incl r2 brb 10$ 20$: movw r1,rec_desc pushaq rec_desc pushaq rec_desc calls #2,g^str$upcase ; start back at zero for new word clrl cur_count ; append a number to the word append_no: pushl #2 pushl #1 pushaq cur_no pushal cur_count calls #4,g^ots$cvt_l_tu movw #rec_size+num_size,cur_pwd pushaq cur_no pushaq rec_desc pushaq cur_pwd calls #3,g^str$concat blbc r0,error_exit pushaw cur_pwd pushaq cur_pwd pushaq cur_pwd calls #3,g^str$trim ; now we have all the info to hash a password $hash_password_s - pwd=cur_pwd,- alg=encrypt,- salt=salt,- usrnam=username,- hash=cur_hash blbc r0,error_exit ; check if we have a match on the hashed password - if so display cmpl cur_hash,pwd bneq no_match cmpl cur_hash+4,pwd+4 bneq no_match pushaq cur_pwd calls #1,g^lib$put_output brb normal_exit ; loop back 'max_count' times no_match: aoblss #max_count,cur_count,append_no ; loop back for another word brb word_loop normal_exit: movl #1,r0 error_exit: ret .end check_password |