otp-1.2.2/0000755000603300000120000000000012343172601011460 5ustar kelvinwheelotp-1.2.2/log.txt0000644000603300000120000000406512343170661013013 0ustar kelvinwheel 2006 November 12 Added includes of and to random.c to avoid a GCC -Wall natter about exit() not being defined. Modified all of the function names in random.c and references to them in otp.c to prefix the names with "o_". This avoid conflicts with the system-supplied random() functions if pulled in by header files we include. Added a version number (1.2 for this release) and date to the -u option output. Created a test.sh test script for Unix separate from the test.bat file for DOS/Windows. Added "./" prefix to run the program from the local directory. Changed the self-test target in the Makefile from "test" to "check". Converted otp.c, random.c, and md5.c to ANSI C. Made the byteReverse internal utility function in md5.c static. When building for Unix, if the system implements /dev/random and we're generating a random seed, 16 bits of entropy from that source is stirred into the mix. 2006 November 13 Added WIN32 code to otp.c to obtain assorted entropy from Windows API calls. Created Visual Studio .NET Onetime.sln and Onetime.vcproj files to build a Win32 console application. Built and tested with the test.bat script. The executable, which is built as Release\Onetime.exe was copied to otp.exe in the main directory. 2012 June 6 Applied to patches from Colin Tuckley to correct problems when building on 64-bit architectures. Updated version to 1.2.1, May 2012. 2014 June 2 Fixed an inconsistency in the declaration of o_random() between random.c and otp.c, and in the process converted the entire program to use and its types throughout, eliminating the ugly and non-portable sensing of architectures within the code. Corrected a sizeof() reference to a pointer to a structure in md5.c which caused a warning in gcc 4.8.1. Changed the make target to build the distribution to "dist" in keeping with contemporary community standards. Modified the distribution creation procedure to make a distribution which unpacks into a directory named otp-$(VERSION) rather than the current directory. Updated version to 1.2.2, June 2014. otp-1.2.2/otp.exe0000644000603300000120000014000010526112436012761 0ustar kelvinwheelMZ@ !L!This program cannot be run in DOS mode. $_ÔÔÔޔÔÔڔÔ”!Ôߔ^ÔÔRichÔPELXE pP+@<.textPmp `.rdata @@.datax, @SUl$ EV5@W=@^u; @+4Ή |XSҋ4@@h@h@/h@h@ h@h@hX@h@h@h@h<@h@@h,@h@h @h@ÐVW3@$Vz3@|_^Ð\@3$\SUV3҉$dW$p23;L$(t$$T$,T$DD$D$OT$D$ @T$8D$ $d$$tL$v=l$@}P؉\$<D$D$H}D$H$QT$ t%p@u+PR$R$ @$@$D$`PDŽ$D$d @L$dT$lD$t$L$0Q$$@T$0D$4j$$wh$Q$R$u $PL$TQP t$Q@d$FN3ҊvhW  R @|T$X3~D$XF;|L$(;D$D$D$D$,tMD$38L$$~Ǚu~-F* D$0FG;|D$DuQD$3IL$$~Ǚu~-FT$D$FG;|=h@33|  @@;}\$t$@ˊЋD$Ht[D$0>+|$Fc<@33Ʌ|kh@A;}|$$~ řu-FD$0EHD$0u\$*  3:ӆT$Pً ωJΉJJ_JJ ^]J [<ÐS\$CUl$ ;VWKsCs?stRt$@+;|L$ȃsVS D$T$ ЃT$+@rID$t$CCPST$ D$@@HT$D$ut${͋ʃ_^][ÐVt$ F?W|0?+G3s2ʃ~WVW3ʃ~FNWVFPNTD$ ֋ JHJHR P _^Ðh@@th@P@tt$t$@̡t@tVW @@3;ϋsu?tу;ru,h.@@ƿ@;YstЃ;r3_^UV3F95L@Wuu$@P @} E5H@D@uR l@t)h@;tСh@;l@h@s @(@;ƋstЃ;r,@0@;ƋstЃ;r}_^uuL@Y]jjt$ 1 jjt$ jjj jjj UVWuEPu uuV_^]á`@Vj^u;}ƣ`@jPYYD@ujV5`@YYD@ujX^3ҹp@D@  @|3ҹ@@@tu B@|3^?=D@tVt$F W@t:t4V VvB }Ft PfYǃf _^U VuWEPu EPEEBuu tMxE EPjYY_^UQQEP(@EMj*h!NbQPMtÃ= @Vt$u;5 @w VdYu#uF= @tVj5@,@^Ã|$w"t$Yu9D$tt$ Yu35l@t$YYv!u @Pt$t$t$j@t$ t$ Vt$FP!YuF-t+uF30| 90t AF݃-^uUQQ=|@S]=0@t s%=@~ jSYY @Xt}@DJtejE]X e3]@j5@MjQPEPh5|@v! t%uEM3e a|zC~[UQEHw @A[V5@DV^tejEMX eE3@j5|@M 5@QPEPj$uE #E jhЈ@'ejjz&YY3@ËeMj@; @u=\@tU)t$'h@YYjh@o'.e>V4@N @F@V@v 5@t 5@£@3W@f8MZuH<ȁ9PEuA= t= t}'v39ytv39EWfYu!=\@t`(j&hYY} }jY0@@@,T@+}jY)}j YE;tPY,@0@P5$@5 @o u9}uV+E MPQ'YYËeu؃}uVwMƍe%V5l@.Y h@l@+Ѓ;sN;sQP-YYuV5l@ -YYu^Ë h@+ l@l@ h@D$h@^t$uYHh9Yl@ujXà l@h@3j h@$E䘏@}䘏@s"eEt 3@ËeME$j h@$E䠏@}䠏@s"eEt 3@ËeME$Vt$v-Ytr@u3 @u^3@P@fF uMSW<`@?u SCYuFjFXFF ?~>^^fN _3[@^3^Ã|$Vt!t$ F t(V f f&fD$ @ tP Y^A @tyt$Ix  QP YYu UVMEM >t} ^]G @SVt!uD$ L$ C>t|$ ^[UT@3ESE3EEEԋE 3Ʉ5VWMG}}  |x@3@jY;E$7@3MEĉẺE܉EEEà t;t-tHHtMMM}MtMk*u!EE@EQM]EEˍDAЉE0e'*uEE@E MEˍDAЉEIt.ht ltwMMM <6u4uGGM} <3u2uGGe} -uMFuV(YiHHt^HHE'EIf8t@@u+Epu@EEI8t@u+ELEMEE+EQE0EEEEMEE E@t fMfMEE Et@t@@@@u3@t|s ؃ڀMu؋u3}} Ee9E~E ueuEM t$ERPWSs'09]؋~MЈN̍E+FEEut΀90uu MM0@E}]@t&tE-tE+ t E Eu+u+u uuEVj u}EMYtuWVj0E }tA}~;E]EM3fPEP&CYCY~'}PEM}YuuMEYEtuEVj f }t ueY} _^M3ME[*2@0@0@1@P1@Y1@1@c2@DhYu@@$@ `@ @@;rSVWD$ PD@f|$>D$@0Uh;.|95$@}RD@h Yt8$@ `@ ;r95$@|5$@3~Ft6Mt.u P@@t@@σȋ MHGE;|]3ۡ@@4؃>uMFujX HP<@tW@@t %>uN@u NNC|5$@8@_^3[DSVt$ t$WuF3w9= @u; @w S Yu+Vj5@,@u"=l@tVYuSjWs$ _^[VWj^395`@~DD@t/@ t PYtG|D@4&D@$YF;5`@|_^SVt$ F Ȁ3ۀu:ft4FW>+~'WPvA$ ;uF yF N _Ff^[Vt$u V,Y^VYt^F @tv%Y^3^SVW33395`@~MD@t8H t0|$uPYtC|$utPxYu F;5`@||$t_^[jYVt$t-= @Vu7YVt PVYY^j5@H@^SUVW|$;=$@@@D0tiW&Yt<tuj&j&;YYtW&YPP@u L@3W)&d0Yt U$Y3%@@ _^][Vt$F ttvff 3YFF^USVu F ^@tfNF F fe f F u"@t@u SYuV&YfF WtaF>HN+IN~ WPS!E 0t@@˃@@ t jjS% FM3GWEPSa! E 9} _tN E% F ^[]SVD$ uL$D$3؋D$ Aȋ\$T$D$ ud$ȋD$r;T$wr;D$ vN3ҋ^[= @u =@r3@jX39D$jhPX@@t* @uhYu5@T@33@h@j5@,@@uËL$%@%@@3 @@@á@ @ T$+P r ;r3UMAVu W+y iDMIMS1UVUU] utJ?vj?ZK;KuB sL!\D u#M!JL! uM!Y] S[MMZU ZRSMJ?vj?Z]]+u]j?u K^;vMJ;։Mv;t^M q;qu; s!tDLu!M!1K!LuM!qM qINM qINu ]}u;M ыYN^qNqN;Nu`LM Ls%}uʻM DD )}uJM YJꍄ ED0E@ @5\@h@H SQ֋ @@ P@@ @@@HC@HyCu `@xuiSjp ֡@pj5@H@@@ȡ@+ȍLQHQP"E @;@vm@@E@=@[_^á@ @W3;u4DPP5@W5@d@;u3_Ã@@@ @VhAj5@4,@;ljFu3Cjh hW`@;ljF uvW5@H@ЃN>~@F^_UQQMASVqW3C}i0Dj?EZ@@Jujhy hW`@up;UwC+ GAH@PǀIuˋUEO HAJ HAdD3GFCENCu x!P_^[U MASVuW} +Q iDMOI;|9M]UE;;MI?Mvj?YM_;_uC sML!\D u&M!ML! uM!YO_YOyM+M}}M O?L1vj?_]][Y]YKYKY;YuWLM Ls}uϻM DD }uOM YO U MD2LU FBD2<38/] )uNK\3uN?] Kvj?^EuN?vj?^O;OuB st!\Du#M!NL! uM!Y] OwqwOquuuN?vj?^M yK{YKYK;KuWLM Ls}uοM 9DD }uNM yN ED3@_^[UM@@SMVWI <}} M 3E@؉u;K;#M# u ;]]r;]u$K;#M# u ;؉]r;@CUt|D#M# u6#UeHD1#u ֋uu#UE9# tUiDMLD3#um#Mj _^{u ];]r;]u& {u ;؉]r;u؅ۉ]tSYKC8$3zG}MT +MN?M~j?^;J;Ju\ }&M|8Ӊ]#\D\Du3M]! ,OM|8!]u ]M!K]}JzyJzyM yJzQJQJ;Ju^LM L}#} u ;οM |D)} u N {MN 7Mt LMuэN L2uɍy>u;@uM; @u%@MB_^[áh@tt$ЅYt3@3UQQSV5@W} 3=YtU@;Yt7VPvYY8u5T@T@d@3Y]_^[5,@,@UQS] 39UWt ME98"u3Ʌ@ѱ"-tG@@t tG@ɋ] t2u t utge8 t u@H8}t ME93C3@B8\t8"u&u}t H9"u339MMt t\GJutH}u t= t8t.t@tG@G@t@@ht'G] !Et _[UQQSVW39=p@u%@h@VW@@@;lj5<@t8uލEPWu3ɋ;uEP u%EP >Wu EHY @Y=$@3_^[QQ@SUVW=@33;j]u-׋;t @L@xu ţ@@u};u׋;tyf9tf9uf9u=l@SSS+S@PVSSD$4׋;t2UJ;YD$t#SSUPt$$VSSׅut$Y\$\$V@P;t;t3D@;t8t @8u@8u+@U;Yu3 UVW# V@_^][YY=săPQL$-=s+ȋą@PS\$UWut$kYDVt$u S6Y,= @3SaY;5 @wHVSUF t1VYt(CH;rPSWASSU8uWYt3$@ @@`@ ;r_^][ËD$;$@VWsR<@@<u6= @S\$utHtHuSjSjSj@3[%@@ _^ËL$; $@VWsU<@@@t78t2= @u3+tItIuPjPjPj@ 3%@@ _^ËD$;$@s @@@tÃ%@@ ËD$;$@SVWse<@@D1tHPYtCt$jt$P@؃uL@3t PsYD0 %@@ _^[P@hYL$At I AI AAAAaUWVu M};v;|ur)$ e@Ǻr $ d@$e@$d@0d@\d@d@#ъFGFGr$ e@I#ъFGr$ e@#ъr$ e@Ie@d@d@d@d@d@d@d@DDDDDDDDDDDDDD$ e@e@$e@0e@De@E^_ÐE^_ÐFGE^_ÍIFGFGE^_Ðt1|9u$r $f@$Xf@IǺr +$e@$f@e@e@f@F#шGr$f@IF#шGFGr$f@F#шGFGFGV$f@I\f@df@lf@tf@|f@f@f@f@DDDDDDDDD D DDDD$f@f@f@f@f@E^_ÐFGE^_ÍIFGFGE^_ÐFGFGFGE^_UM S3ۄVE ]y ]E eEu@u9и@tMj^#+tHt Hu0EE@EEt> t00t"@t@@uE E]#¹;W/t(;t$;t=tH=u)EHE?u:=t,=t;t!@@SEEE Ǿt @#Mx3F@tM= @uMt t t؃;u%@@jVuEPuuu@;tV@@uVP@L@PY빃uM@ uMVSEYY <@@EeHD1u+y'E t!jjS Eu(=@u[}uE t D0 _^[ÀejEPSo u}uuSYYtjjS+ uSYU-t"t t Ht3øøøøWj@3Y@3@ظ@Ը@@_U@3EVEEP5@Ā@ 3@;rEƅ t6SUW ;w+A ˃BBu_[j5Ը@5@PVPj"j5@VPVPV5Ը@Bj5@VPVPh5Ը@\3fEt@@t@ 〠@@;rD3ArZw@Ȁ @arzw@ Ȁ @@;rM3M^U@3ESVu3ۃEW@u@@+u@@u@@E;5@c;Q339@tg0B=rEPVĀ@j@3Y@3G9}5@Ը@}MAj@3Y@ R]@)Vt&;wU@@@;vFFuE}rE@ظ@@@Ը@\@@;vAAyKǀ@@=rrԸ@=ظ@ظ@3@ 9@tu3M3M_^[Ã=p@ujYp@3U @3EejEEPhuȀ@u EP迻YM3M薽j8h؎@6@3EE3}}܋E]؉}ԋE;E sMQP5Ā@օt }uEPu օt }uE9}tt u)YFuu9}uWWSujup@u;tX}6e܉]6PWSz M3@Ëe33ۃMu;uVjiYY;u3EVSuujup@9}t WWuuVSWu l@tfEE^9}uWWWWVSWu l@;tCVjYYE;t2WWVPVSWu l@;uuY}}t M]9}tSYEeM3M˻UHSVWjXjEPSԀ@tq}EPЀ@Ep#+E @IɁ;r7tJ߿jEPSԀ@t]}tE]t3@8;s30jWuS`@ @H%MQ@PuS̀@e_^[US39@VWumhH@@;5@h<@Wօ@t|h,@Wh@W@փ= @ĸ@uh@Wօ̸@t h@W֣ȸ@ȸ@t<ЅtMQj MQjP̸@tEu=@r M )35M@tЋ؅tĸ@tSЋuu uS@_^[W|$n$L$Wtt=u~Ѓ3ƒtAt#ttt͍y yyyL$ ttfu~Ѓ3‹tt4t'ttljD$_fD$G_fD$_ÈD$_̋L$ WVSًt$|$u 't+t/uuatt7uD$[^_tuutu[^D$_Ét~Ѓ3‹t܄t,tt uĉ3҉3t 3uwD$[^_VC20XC00USVWU] E@EEEECs {ta v|tEVUkT]^] t3x<{SkVS vjDaC T{ v4롸UkjS]]_^[]UL$)APAPy]UWVu M};v;|ur)$ v@Ǻr $ u@$v@$u@0u@\u@u@#ъFGFGr$ v@I#ъFGr$ v@#ъr$ v@Iv@u@u@u@u@u@u@u@DDDDDDDDDDDDDD$ v@v@$v@0v@Dv@E^_ÐE^_ÐFGE^_ÍIFGFGE^_Ðt1|9u$r $w@$Xw@IǺr +$v@$w@v@v@w@F#шGr$w@IF#шGFGr$w@F#шGFGFGV$w@I\w@dw@lw@tw@|w@w@w@w@DDDDDDDDD D DDDD$w@w@w@w@w@E^_ÐFGE^_ÍIFGFGE^_ÐFGFGFGE^_j訳YUQQE;$@VWsr<@@D1tUM MMPMaYtDuMQuP@EuL@t PEY"D0 EU%@@ _^U@3ES]V3;$@E@@˃DjVS EjVS W} +~ohVPhSE;}PPSQ t+=@u @ uSDYY@}>ju SESP @Nu@ L@@juS _ @ M3M^[蟱USVu;5$@W@@ƊPe}} t]uXHt@< tMOED0 jEPuQ40@u0L@jY;u @/mu30PY!UUL0t ? u $E M;EME<< t GEI9MsE@8 uEYEpEjEPjEP40@u L@uH}tBD0HtE< t D1*;} u } u jjjur} t GM9MJt0@u +} }E%@@ _^[USVWUjjh{@uN]_^[]ËL$AtD$T$SVWD$Pjh|@d5d%D$ Xp t.;t$$t(4v L$H |uhD@Td _^[3d y|@uQ R 9QuSQ@ SQ@MKCk Y[D$;$@Vs[ @@T tA3%9t$ u |$ @uɀ%ƈ ^@ @ ^%؀@̐.<Nbv‘ґ 0>LZhx’Ғ&<R^zƓ"0:FRdv”XE@TT http://www.fourmilab.ch/ by John Walker Version 1.2, November 2006 80 -Wn Output lines <= n characters -U Print this message 4 -Sn Separator every n characters -Rseed Set seed for random number generator 50 -Nn Generate n keys -Msigfile Write MD5 signatures of keys in sigfile 8 -Ln Lower case letter keys of n characters -En English word-like keys of n characters -Dn Numeric digit keys of n characters -Cn Capital letter keys of n characters Defaults Options Usage: otp [options] [output_file] otp -- One-time pad generator. Cannot allocate password buffers. %02X%s %*d) %s Cannot create output file %s Error: duplicate output file specification. Cannot create MD5 signature file %s wCorExitProcessmscoree.dll ((((( H h(((( H H+@+@[-@o-@~.@.@.@.@EEE50P (8PX700WP `h````ppxxxx(null)(null)-O@1O@*M@.M@M@M@P@P@Microsoft Visual C++ Runtime LibraryProgram: ...A buffer overrun has been detected which has corrupted the program's internal state. The program cannot safely continue execution and must now be terminated. Buffer overrun detected!A security error of unknown cause has been detected which has corrupted the program's internal state. The program cannot safely continue execution and must now be terminated. Unknown security failure detected!;R@?R@runtime error TLOSS error SING error DOMAIN error R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point not loaded Runtime Error! Program: n@n@GetProcessWindowStationGetUserObjectInformationAGetLastActivePopupGetActiveWindowMessageBoxAuser32.dllRSDS(˅O cBw$nMf:\Projects\Onetime\Release\Onetime.pdb"̐.<Nbv‘ґ 0>LZhx’Ғ&<R^zƓ"0:FRdv”GlobalMemoryStatusGetTickCountKERNEL32.dll GetCursorPosGetActiveWindowUSER32.dllExitProcessGetProcAddressgGetModuleHandleA1TerminateProcess/GetCurrentProcessGetSystemTimeAsFileTimeHeapAllocGetCommandLineAGetVersionExASetHandleCountGetStdHandlePGetFileTypeGetStartupInfoAHeapFreeZGetLastError,CloseHandleHeapDestroyHeapCreateXVirtualFreeUVirtualAllocHeapReAlloc LCMapStringAiWideCharToMultiByteQMultiByteToWideChar!LCMapStringWGetStringTypeAGetStringTypeW~QueryPerformanceCounter2GetCurrentThreadId0GetCurrentProcessIdeGetModuleFileNameAvWriteFileBUnhandledExceptionFilterFreeEnvironmentStringsA?GetEnvironmentStringsFreeEnvironmentStringsWAGetEnvironmentStringsWHeapSizeFlushFileBuffers SetStdHandleSetFilePointerJCreateFileAGetACP|GetOEMCPGetCPInfo]GetLocaleInfoA[VirtualProtectGetSystemInfo]VirtualQuery.LoadLibraryASetEndOfFileReadFileRtlUnwindQ@Y'@).@m@'@?91$21fB];޵o @HkIt۱Y\Teh.y=kC-*.gڈʈ]si5O֏Qokna?A6"Ƹ*{׈ "G'x@l@l@@4  >SL  7   E! 2  ( A 85T7}3(276#%A   3/#  e9, (3 &8 .Ou , >*5 !4@% * /z?j  6,|  _) [*7% !SM <%7 A  I /K 8 0t#9LJ~ O128    /'H$&!$   '_sw]c{?7j=h~-`@`@„@ʆ@.N@&@|@l@ @d@ 8@ @p@@@@@@@X@ @@x@y؋@zȋ@ċ@@  w@w@w@w@w@w@        ! 5A CPR S WY l m pr   )    `y!@~ڣ @ڣ AϢ[@~QQ^ _j21~ otp-1.2.2/Onetime.sln0000644000603300000120000000162210526106362013601 0ustar kelvinwheelMicrosoft Visual Studio Solution File, Format Version 7.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Onetime", "Onetime.vcproj", "{A553E5A1-9AC8-47B8-9910-F2F3392CA4F8}" EndProject Global GlobalSection(SolutionConfiguration) = preSolution ConfigName.0 = Debug ConfigName.1 = Release EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {A553E5A1-9AC8-47B8-9910-F2F3392CA4F8}.Debug.ActiveCfg = Debug|Win32 {A553E5A1-9AC8-47B8-9910-F2F3392CA4F8}.Debug.Build.0 = Debug|Win32 {A553E5A1-9AC8-47B8-9910-F2F3392CA4F8}.Release.ActiveCfg = Release|Win32 {A553E5A1-9AC8-47B8-9910-F2F3392CA4F8}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal otp-1.2.2/md5.c0000644000603300000120000001740112343165443012322 0ustar kelvinwheel/* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. */ #include /* for memcpy() */ #include "md5.h" /* * Note: this code is harmless on little-endian machines. */ static void byteReverse(unsigned char *buf, unsigned longs) { uint32_t t; do { t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]); *(uint32_t *) buf = t; buf += 4; } while (--longs); } /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(struct MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bits[0] = 0; ctx->bits[1] = 0; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len) { uint32_t t; /* Update bitcount */ t = ctx->bits[0]; if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++; /* Carry from low to high */ ctx->bits[1] += len >> 29; t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ /* Handle any leading odd-sized chunks */ if (t) { unsigned char *p = (unsigned char *) ctx->in + t; t = 64 - t; if (len < t) { memcpy(p, buf, len); return; } memcpy(p, buf, (int) t); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += t; len -= (unsigned) t; } /* Process data in 64-byte chunks */ while (len >= 64) { memcpy(ctx->in, buf, 64); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memcpy(ctx->in, buf, len); } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) { unsigned count; unsigned char *p; /* Compute number of bytes mod 64 */ count = (unsigned) (ctx->bits[0] >> 3) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ p = ctx->in + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = 64 - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); /* Now fill the next block with 56 bytes */ memset(ctx->in, 0, 56); } else { /* Pad block to 56 bytes */ memset(p, 0, count - 8); } byteReverse(ctx->in, 14); /* Append length in bits and transform */ ((uint32_t *) ctx->in)[14] = ctx->bits[0]; ((uint32_t *) ctx->in)[15] = ctx->bits[1]; MD5Transform(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ void MD5Transform(uint32_t buf[4], uint32_t in[16]) { uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } otp-1.2.2/Onetime.vcproj0000644000603300000120000000605510526107476014324 0ustar kelvinwheel otp-1.2.2/otp.10000644000603300000120000001740512343170407012355 0ustar kelvinwheel.TH OTP 1 "2 JUN 2014" .UC 4 .SH NAME otp \- generate one-time key pads or password lists .SH SYNOPSIS .nh .na .B otp [ .BI \-c chars 'in +6n .BI \-d digits .BI \-e chars .BI \-l chars .BI \-m sigfile .BI \-n nkeys .BI \-r seed .BI \-s nchars .B \-u .BI \-w linelen .I outfile ] .in -6n .hy .ad .SH DESCRIPTION Systems which use passwords and/or encryption keys to authenticate an individual's identity or protect against interception of communications achieve the highest degree of security when each password or key is used .IR "only once" . Spies are furnished ``one-time pads'' containing pages of keys used to encrypt individual characters of secret messages, then discarded. As long as the physical security of the two copies of a one-time pad is assured and the keys on the pad are sufficiently random, security is absolute. .PP Swiss banks which accept electronic payment orders use a similar mechanism to verify the identity of the issuer of an order. When a client authorises the bank to accept electronic orders, the bank delivers, by registered mail, a list of individual session passwords (usually numbers of 4 to 6 digits). The customer agrees to keep the list of passwords physically secure, and to not hold the bank liable if the customer allows the list to fall into unauthorised hands. Each time an order is given, in addition to the regular user identity and password, the next key from the list must be entered, and then crossed off by the user. The bank verifies the key against a copy of the list stored in their own secure computer, and only if the key matches is the order accepted. Multiple incorrect entries block electronic access to the customer's account until re-enabled by the customer providing suitable verification that an unauthorised access attempt did not, in fact, occur. .PP Note that even if the customer's entire communication session with the bank is intercepted, the eavesdropper will not be able to subsequently issue orders in the customer's name since the one-time password used in the compromised session will never be used again, and provides no usable clue as to subsequent one-time passwords. .PP .B otp creates key and password lists for verification and security purposes in a variety of formats. Keys can be of any length, consist of digits or letters (capital or lower case), and alphabetic passwords can either be entirely random (most secure) or obey the digraph statistics of English text (easier to remember when transcribing, but less secure). .PP For computer applications, for example one-time login passwords, .B otp can create a file containing the MD5 signature of each of the generated keys. This permits the computer to verify keys without the need to store the keys in plaintext. As noted below, this improves security only if keys are sufficiently long to deter exhaustive search for their signatures. .SH OPTIONS .TP 12 .BI \-c chars Generate keys consisting of .I chars (default 8) capital letters. The keys consist of random letters unless the .B \-e option is also specified, in which case they obey the digraph statistics of English text. .TP .BI \-d digits Generate keys consisting of .I digits (default 8) decimal digits. .TP .BI \-e chars Generate keys consisting of .I chars (default 8) letters which obey the digraph statistics of English text. Such keys are usually easier to remember when transcribing from a printed pad to a computer, but are less secure than entirely random sequences of letters. Keys default to lower case letters; specify the .B \-c option along with .B \-e if you prefer capital letters. .TP .BI \-l chars Generate keys consisting of .I chars (default 8) lower case letters. The keys consist of random letters unless the .B \-e option is also specified, in which case they obey the digraph statistics of English text. .TP .BI \-m sigfile A file .I sigfile is written which contains the MD5 signature of each of the generated keys, with each 128 bit signature written as 32 hexadecimal digits on a line by itself. Computer applications can use this signature file for verification when the user supplies a key, rather than storing a copy of the keys as plaintext. Note that if the MD5 signature file is compromised, short keys are still vulnerable since their MD5 signatures can be found by exhaustive search. .TP .BI \-n nkeys Generate .I nkeys keys. By default, 50 keys are generated. .TP .BI \-r seed The string .I seed is used to initialise the random number generator. Every run of .B otp with the same seed will produce the same output. This is primarily useful for testing, but it also allows users at different locations to produce identical sheets given only a seed known to both. If you're about to use up all the keys on a sheet, you can generate a new pair of sheets by using the last key on the sheet as the seed for a new one. (This is not as secure as physically exchanging a new pair of sheets, but if you're about to run out of keys, it's better than nothing.) If the .B \-r option is not specified, the generator is initialised with a value derived from the date and time and various system environment information; each run will produce a different sheet. .TP .BI \-s nchars Include a hyphen separator every .I nchars characters in the keys. Breaking up long keys into segments with separators makes them easier to transcribe. By default, a hyphen is inserted every 4 characters. .TP .B \-u Print how-to-call information. .TP .BI \-w linelen Format output so lines are less than or equal to .I linelen characters (unless individual keys exceed the line length). The default line length is 79 characters. .SH FILES If no .I outfile is specified, output is written on standard output. .SH "APPLICATION NOTES" If you're using .BR otp -generated keys for computer system passwords, it's wise to include one or more non-alphanumeric characters and to mix upper and lower case letters; this makes your password much more difficult to guess by exhaustive search. For example, if .B otp generated a password of .B jxuc-uiuf and you're using a system on which passwords are limited to 8 characters, you might actually use .B jXu&uIU= as your password. .PP When using one-time keys to communicate with other people, it's often a good idea to supply both the current session key and the key for the previous session. It's easy to forget to cross off a key after using it; including the previous key makes it easier to discover if this has happened and get back in sync. Similarly, in computer-based authentication systems it's a good idea to respond to entry of an incorrect key by prompting the user with the key from the last session. .PP Pseudorandom numbers on which entries in the pads are based are generated by the exclusive-or of four concurrently-running BSD .BR random () generators, each with 256 bytes of state, independently seeded from 4 byte segments of the 16-byte MD5 signature of the original seed. .SH "SEE ALSO" .PD .BR random (3) .ne 5 .SH EXIT STATUS .B otp returns status 0 if processing was completed without errors, and 2 if an error prevented generation of output. .SH ACKNOWLEDGEMENTS The English-digraph frequency key generator is based on the ``mpw'' program developed at MIT, which was converted from Multics PL/I to C by Bill Sommerfeld, 4/21/86. The original PL/I version was provided by Jerry Saltzer. .PP The implementation of MD5 message-digest algorithm is based on a public domain version written by Colin Plumb in 1993. The algorithm is due to Ron Rivest. The algorithm is described in Internet RFC 1321. .SH AUTHOR .RS 4 .nf John Walker .fi .RE .PD .PP This software is in the public domain. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, without any conditions or restrictions. This software is provided ``as is'' without express or implied warranty. otp-1.2.2/test.bat0000744000603300000120000000047106342042410013126 0ustar kelvinwheelotp -rTEST -n4 -mt1.md5 >test.out otp -rTEST -n3 -c12 -mt2.md5 >>test.out otp -rTEST -n3 -e12 -mt3.md5 >>test.out otp -rTEST -n4 -S5 -e -c -mt4.md5 >>test.out otp -rTEST -n7 -d4 -mt5.md5 >>test.out type t1.md5 >>test.out type t2.md5 >>test.out type t3.md5 >>test.out type t4.md5 >>test.out type t5.md5 >>test.out otp-1.2.2/md5.h0000644000603300000120000000101112343164535012316 0ustar kelvinwheel#ifndef MD5_H #define MD5_H #include struct MD5Context { uint32_t buf[4]; uint32_t bits[2]; unsigned char in[64]; }; extern void MD5Init(struct MD5Context *ctx); extern void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len); extern void MD5Final(unsigned char digest[16], struct MD5Context *ctx); extern void MD5Transform(uint32_t buf[4], uint32_t in[16]); /* * This is needed to make RSAREF happy on some MS-DOS compilers. */ typedef struct MD5Context MD5_CTX; #endif /* !MD5_H */ otp-1.2.2/test.mas0000644000603300000120000000173306342042431013144 0ustar kelvinwheel1) gtwe-uzpy 2) chog-inzx 3) moum-mmqd 4) tscc-jgwq 1) GTWE-UZPY-CHOG 2) INZX-MOUM-MMQD 3) TSCC-JGWQ-JQRX 1) tbrs-ttsi-ncep 2) aspu-resc-dffi 3) rarc-eera-dutr 1) TBRST-TSI 2) ITUSA-SPU 3) COPED-FFI 4) RARCE-ERA 1) 0782 2) 0790 3) 8982 4) 2559 5) 6806 6) 8809 7) 9046 04AE0013DFAC7807A4846425AAE03D48 5C35E01460B99DCFD633C452DDA3D88F 3AB54DB185D43A93456A92B9AA99EE62 12C922490E68C90F8A59CA2CA96181D3 03BF87A4039FDE7F3E6B8214D7162B59 2A5E8F30370AB9DF07757547152D1A80 81FAAEC483AFE76719AC68ADF1295AF5 9C1677DD981B356208D20A546C8D70EF CFE3A6207FE539C177E17B23EBB86883 93E1B359ECDCDCAB3AF73295BCC409B8 7404FDFF86B09436C91DA8FD54E3CD75 02929F09EA49E0061EB782444F4344BC 30A1D94D0D7A724BD2FFCF1668CD7668 9B1F342D9A7A87578FAAE8B3BF1911A4 4412F9B5319371806D61CDB46DC1D850 0111CE77801C36B76B07263F4DDA44CA 37CA649D980EAA5564A620F959F12D88 B5BAA9C23AC3E015AD287B17A3D4AFA3 DA87CBC1B5B8501ACF3B49EEC1CC52C3 F37C4630C796617ACE93E19C350C321E 71C1806CA28B555C76650F52BB0D2810 otp-1.2.2/Makefile0000644000603300000120000000145512343170346013131 0ustar kelvinwheel CC = gcc #CFLAGS = -g -DDEBUG CFLAGS = -O -Wall VERSION = 1.2.2 PAGER = less FILES = Makefile Onetime.sln Onetime.vcproj README log.txt md5.c \ md5.h otp.1 otp.c otp.exe random.c test.bat test.mas test.sh otp: otp.o md5.o random.o $(CC) $(CFLAGS) otp.o md5.o random.o -o otp manpage: nroff -man otp.1 | $(PAGER) printman: groff -man otp.1 | lp otp.man: otp.1 nroff -man otp.1 | col -b >otp.man dist: clean mkdir otp-$(VERSION) cp -p $(FILES) otp-$(VERSION) tar cfv otp-$(VERSION).tar otp-$(VERSION) rm -f otp-$(VERSION).tar.gz gzip otp-$(VERSION).tar rm -rf otp-$(VERSION) check: otp chmod u+x test.bat ./test.sh diff test.mas test.out clean: rm -f *.bak *.o otp test.out *.shar core core.* \ *.obj *.pdb *.sbr *.bsc *.vcw *.bin t?*.md5 \ *.gz *.tar rm -rf otp-$(VERSION) otp-1.2.2/otp.c0000644000603300000120000003634512343164677012457 0ustar kelvinwheel/* One-Time Pad Generator by John Walker http://www.fourmilab.ch/ Creates ready to use one-time pads containing either passwords that obey the digraph frequencies of English text (less secure but easier to remember), completely random letters, or digits. Random values for the pad are generated from the XOR of four concurrently-running BSD random() generators, each with a 256 byte state vector, independently seeded with four 4 byte blocks of the MD5 message digest of a vector containing: Time and date (time()) Several hundred bytes of unitialised storage and, depending on the operating system: MSDOS: Default drive size and free space Absolute address program loaded in memory Unix: Time in microseconds (to system's timer resolution) Process ID number Parent process ID number Machine's host ID The English-digraph password generator is based on the "mpw" program developed at MIT: mpw: Make up passwords which have similar letter digraph frequencies to English. Converted from Multics PL/I by Bill Sommerfeld, 4/21/86. Original PL/I version provided by Jerry Saltzer. This program is in the public domain. */ #define VERSION "1.2.2, June 2014" #include #include #include #include #include #ifdef MSDOS #include #endif #ifdef WIN32 #include #endif #ifdef unix #include extern int getpid(), getppid(), gethostid(); #endif #include "md5.h" #define V (void) /* Globals imported. Depending on your system you may want/need to replace these with includes of the proper header files. */ extern int32_t o_random(); extern char *o_initstate(); extern char *o_setstate(); #define PW_LENGTH 8 /* Default password length */ /* Frequency of English digraphs (from D Edwards 1/27/66) */ static int frequency[26][26] = { {4, 20, 28, 52, 2, 11, 28, 4, 32, 4, 6, 62, 23, 167, 2, 14, 0, 83, 76, 127, 7, 25, 8, 1, 9, 1}, /* aa - az */ {13, 0, 0, 0, 55, 0, 0, 0, 8, 2, 0, 22, 0, 0, 11, 0, 0, 15, 4, 2, 13, 0, 0, 0, 15, 0}, /* ba - bz */ {32, 0, 7, 1, 69, 0, 0, 33, 17, 0, 10, 9, 1, 0, 50, 3, 0, 10, 0, 28, 11, 0, 0, 0, 3, 0}, /* ca - cz */ {40, 16, 9, 5, 65, 18, 3, 9, 56, 0, 1, 4, 15, 6, 16, 4, 0, 21, 18, 53, 19, 5, 15, 0, 3, 0}, /* da - dz */ {84, 20, 55, 125, 51, 40, 19, 16, 50, 1, 4, 55, 54, 146, 35, 37, 6, 191, 149, 65, 9, 26, 21, 12, 5, 0}, /* ea - ez */ {19, 3, 5, 1, 19, 21, 1, 3, 30, 2, 0, 11, 1, 0, 51, 0, 0, 26, 8, 47, 6, 3, 3, 0, 2, 0}, /* fa - fz */ {20, 4, 3, 2, 35, 1, 3, 15, 18, 0, 0, 5, 1, 4, 21, 1, 1, 20, 9, 21, 9, 0, 5, 0, 1, 0}, /* ga - gz */ {101, 1, 3, 0, 270, 5, 1, 6, 57, 0, 0, 0, 3, 2, 44, 1, 0, 3, 10, 18, 6, 0, 5, 0, 3, 0}, /* ha - hz */ {40, 7, 51, 23, 25, 9, 11, 3, 0, 0, 2, 38, 25, 202, 56, 12, 1, 46, 79, 117, 1, 22, 0, 4, 0, 3}, /* ia - iz */ {3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0}, /* ja - jz */ {1, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 2, 1, 0, 2, 0, 1, 0}, /* ka - kz */ {44, 2, 5, 12, 62, 7, 5, 2, 42, 1, 1, 53, 2, 2, 25, 1, 1, 2, 16, 23, 9, 0, 1, 0, 33, 0}, /* la - lz */ {52, 14, 1, 0, 64, 0, 0, 3, 37, 0, 0, 0, 7, 1, 17, 18, 1, 2, 12, 3, 8, 0, 1, 0, 2, 0}, /* ma - mz */ {42, 10, 47, 122, 63, 19, 106, 12, 30, 1, 6, 6, 9, 7, 54, 7, 1, 7, 44, 124, 6, 1, 15, 0, 12, 0}, /* na - nz */ {7, 12, 14, 17, 5, 95, 3, 5, 14, 0, 0, 19, 41, 134, 13, 23, 0, 91, 23, 42, 55, 16, 28, 0, 4, 1}, /* oa - oz */ {19, 1, 0, 0, 37, 0, 0, 4, 8, 0, 0, 15, 1, 0, 27, 9, 0, 33, 14, 7, 6, 0, 0, 0, 0, 0}, /* pa - pz */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0}, /* qa - qz */ {83, 8, 16, 23, 169, 4, 8, 8, 77, 1, 10, 5, 26, 16, 60, 4, 0, 24, 37, 55, 6, 11, 4, 0, 28, 0}, /* ra - rz */ {65, 9, 17, 9, 73, 13, 1, 47, 75, 3, 0, 7, 11, 12, 56, 17, 6, 9, 48, 116, 35, 1, 28, 0, 4, 0}, /* sa - sz */ {57, 22, 3, 1, 76, 5, 2, 330, 126, 1, 0, 14, 10, 6, 79, 7, 0, 49, 50, 56, 21, 2, 27, 0, 24, 0}, /* ta - tz */ {11, 5, 9, 6, 9, 1, 6, 0, 9, 0, 1, 19, 5, 31, 1, 15, 0, 47, 39, 31, 0, 3, 0, 0, 0, 0}, /* ua - uz */ {7, 0, 0, 0, 72, 0, 0, 0, 28, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0}, /* va - vz */ {36, 1, 1, 0, 38, 0, 0, 33, 36, 0, 0, 4, 1, 8, 15, 0, 0, 0, 4, 2, 0, 0, 1, 0, 0, 0}, /* wa - wz */ {1, 0, 2, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0}, /* xa - xz */ {14, 5, 4, 2, 7, 12, 12, 6, 10, 0, 0, 3, 7, 5, 17, 3, 0, 4, 16, 30, 0, 0, 5, 0, 0, 0}, /* ya - yz */ {1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* za - zz */ }; /* This MUST be equal to the sum of the equivalent rows above. */ static int row_sums[26] = { 796, 160, 284, 401, 1276, 262, 199, 539, 777, 16, 39, 351, 243, 751, 662, 181, 17, 683, 662, 968, 248, 115, 180, 17, 162, 5 }; /* Frequencies of starting characters. */ static int start_freq [26] = { 1299, 425, 725, 271, 375, 470, 93, 223, 1009, 24, 20, 355, 379, 319, 823, 618, 21, 317, 962, 1991, 271, 104, 516, 6, 16, 14 }; /* This MUST be equal to the sum of all elements in the above array. */ static int total_sum = 11646; /* Random number generator state vectors. */ #define RandVecL 256 typedef char randvec[RandVecL]; static randvec rvec[4]; /* USAGE -- Print how-to-call information. */ static void usage(void) { V fprintf(stderr, "otp -- One-time pad generator.\n"); V fprintf(stderr, "\n"); V fprintf(stderr, "Usage: otp [options] [output_file]\n"); V fprintf(stderr, "Defaults Options\n"); V fprintf(stderr, " -Cn Capital letter keys of n characters\n"); V fprintf(stderr, " -Dn Numeric digit keys of n characters\n"); V fprintf(stderr, " -En English word-like keys of n characters\n"); V fprintf(stderr, " 8 -Ln Lower case letter keys of n characters\n"); V fprintf(stderr, " -Msigfile Write MD5 signatures of keys in sigfile\n"); V fprintf(stderr, " 50 -Nn Generate n keys\n"); V fprintf(stderr, " -Rseed Set seed for random number generator\n"); V fprintf(stderr, " 4 -Sn Separator every n characters\n"); V fprintf(stderr, " -U Print this message\n"); V fprintf(stderr, " 80 -Wn Output lines <= n characters\n"); V fprintf(stderr, "\n"); V fprintf(stderr, "Version " VERSION "\n"); V fprintf(stderr, "by John Walker\n"); V fprintf(stderr, " http://www.fourmilab.ch/\n"); } /* MRANDOM -- Combine the results of four independently-seeded concurrently running random number generators to produce a random value based on a 16 byte seed. */ static long mrandom(void) { int i; int32_t r = 0; for (i = 0; i < 4; i++) { o_setstate(rvec[i]); r ^= o_random(); } return r; } /* Main program. */ int main(int argc, char *argv[]) { int i, j, row_position, nchars, position, line, lbase, npass = 50, ndig, sep = 4, numeric = 0, upper = 0, english = 0, pw_length = PW_LENGTH, pw_item, linelen = 79, npline, lineno, nch; int32_t rseed; char *password, *pwp, *v, *seed = NULL; FILE *ofile = stdout, *sigfile = NULL; uint32_t trash[100]; struct MD5Context md5c; unsigned char digest[16]; #ifdef MSDOS union _REGS ri, ro; #endif #ifdef unix struct timeval tv; #endif for (i = 1; i < argc; i++) { char *op, opt; op = argv[i]; if (*op == '-') { opt = *(++op); if (islower(opt)) { opt = toupper(opt); } switch (opt) { case 'C': numeric = 0; upper = 1; scanl: if ((j = atoi(op + 1)) > 0) { pw_length = j; } break; case 'D': /* -Dlen Numeric digit keys */ numeric = 1; goto scanl; case 'E': /* -Elen English word like keys */ english = 1; goto scanl; case 'L': /* -Llen Lower case letter keys */ numeric = 0; upper = 0; goto scanl; case 'M': /* -Msigfile Write MD5 signatures of keys in sigfile */ if ((sigfile = fopen(op + 1, "w")) == NULL) { fprintf(stderr, "Cannot create MD5 signature file %s\n", op + 1); return 2; } break; case 'N': /* -Ncount Generate count keys */ npass = atoi(op + 1); if (npass < 1) { npass = 50; } break; case 'R': /* -Rstring Specify seed for random generator */ seed = op + 1; break; case 'S': /* -Schars Insert a separator every chars */ sep = atoi(op + 1); break; case 'U': /* -U Print how to call information */ case '?': usage(); return 0; case 'W': /* -Wn Break lines for a width of n characters */ linelen = atoi(op + 1); break; } } else { if (ofile != stdout) { fprintf(stderr, "Error: duplicate output file specification.\n"); usage(); return 2; } ofile = fopen(op, "w"); if (ofile == NULL) { fprintf(stderr, "Cannot create output file %s\n", op); return 2; } } } lbase = upper ? 'A' : 'a'; ndig = 1; j = 10; while (npass >= j) { ndig++; j *= 10; } pw_item = pw_length + (sep > 0 ? (pw_length / sep) : 0); password = (char *) malloc(pw_item + 1); pw_item += ndig + 5; j = pw_item * 3; if (j < 132) { j = 132; } v = (char *) malloc(j); if (password == NULL || v == NULL) { fprintf(stderr, "Cannot allocate password buffers.\n"); return 2; } npline = linelen / pw_item; if (npline < 1) { npline = 0; } MD5Init(&md5c); if (seed != NULL) { #ifdef DEBUG fprintf(stderr, "Seed string: \"%s\"\n", seed); #endif MD5Update(&md5c, (unsigned char *) seed, strlen(seed)); } else { /* Seed the random generator from the time of day and a variety of system environment information unlikely to be easily guessed. */ #ifdef MSDOS ri.h.ah = 0x36; /* Get disc free space */ ri.h.dl = 0; /* Default drive */ if (_intdos(&ri, &ro) != 0xFFFF) { trash[1] = (((int32_t) ro.x.ax) << 16) | ro.x.bx; trash[2] = (((int32_t) ro.x.cx) << 16) | ro.x.dx; } trash[4] = (int32_t) (char __far *) trash; #define OS_KNOWN 1 #endif #ifdef WIN32 MEMORYSTATUS ms; POINT p; /* The following gets all kind of information likely to vary from moment to moment and uses it as the initial seed for the random number generator. If any of these causes porting problems in the future, just delete them. */ trash[1] = GetTickCount(); trash[2] = (unsigned long) (((HWND) NULL) - GetActiveWindow()); trash[3] = GetFreeSpace(0); ms.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(&ms); trash[4] = ms.dwMemoryLoad; trash[5] = (unsigned long) ms.dwAvailPhys; trash[6] = (unsigned long) ms.dwAvailPageFile; GetCursorPos(&p); trash[7] = p.x; trash[8] = p.y; #define OS_KNOWN 1 #endif #ifdef unix FILE *rf; size_t ct; gettimeofday(&tv, (struct timezone *) NULL); trash[1] = tv.tv_sec; trash[2] = tv.tv_usec; /* If any of these don't exist on your system, just delete the call and/or replace it with something else in the environment. */ trash[4] = getpid(); trash[11] = getppid(); trash[38] = gethostid(); /* If the system implements /dev/random, obtain 16 bytes of entropy thence. */ if ((rf = fopen("/dev/random", "r")) != NULL) { ct = fread(&(trash[60]), 1, 16, rf); if (ct == 0) { fprintf(stderr, "No data read from /dev/random.\n"); } fclose(rf); } #define OS_KNOWN 1 #endif #ifndef OS_KNOWN fprintf(stderr, "No operating system sensed in otp.c compile.\n"); exit(2); #endif trash[0] = (unsigned long) time(NULL); MD5Update(&md5c, (unsigned char *) trash, sizeof trash); } MD5Final(digest, &md5c); for (j = 0; j < 4; j++) { rseed = (((int32_t) digest[0 + (4 * j)]) << 24) | (((int32_t) digest[1 + (4 * j)]) << 16) | (((int32_t) digest[2 + (4 * j)]) << 8) | digest[3 + (4 * j)]; o_initstate(rseed, rvec[j], RandVecL); #ifdef DEBUG fprintf(stderr, "Digest[%d : %d]:", j * 4, (j * 4) + 3); for (i = 0; i < 4; i++) { fprintf(stderr, " %02X", digest[i + (4 * j)]); } fprintf(stderr, "\n"); fprintf(stderr, "Seed[%d]: %08lX\n", j, rseed); #endif } /* "Cook" the random number generator for a random number of cycles to gnarl things up some more. */ for (i = 0; i < (28 + digest[8]); i++) { (void) mrandom(); } #ifdef RTEST { char rt[1024]; FILE *fo = fopen("rtest.bin", #ifdef MSDOS "wb" #else "w" #endif ); for (i = 0; i < 64; i++) { for (j = 0; j < 1024; j++) { rt[j] = mrandom() >> 7; } fwrite(rt, sizeof rt, 1, fo); } fclose(fo); exit(0); } #endif v[0] = 0; lineno = 0; for (line = 1; line <= npass; line++) { if (numeric) { pwp = password; for (nchars = 0; nchars < pw_length; nchars++) { if ((sep > 0) && ((nchars % sep) == 0) && (nchars > 0)) { *pwp++ = '-'; } *pwp++ = '0' + (int) ((mrandom() >> 7) % 10); } } else if (!english) { pwp = password; for (nchars = 0; nchars < pw_length; nchars++) { if ((sep > 0) && ((nchars % sep) == 0) && (nchars > 0)) { *pwp++ = '-'; } *pwp++ = lbase + (int) ((mrandom() >> 7) % 26); } } else { position = (int) (mrandom() % total_sum); for (row_position = 0, j = 0; position >= row_position; row_position += start_freq[j], j++) continue; *(pwp = password) = j + lbase - 1; nch = 1; for (nchars = pw_length - 1; nchars; --nchars) { i = *pwp - lbase; pwp++; /* Now find random position within the row. */ position = (int) (mrandom() % row_sums[i]); for (row_position = 0, j = 0; position >= row_position; row_position += frequency[i][j], j++) continue; if ((sep > 0) && ((nch % sep) == 0)) { *pwp++ = '-'; } nch++; *pwp = j + lbase - 1; } pwp++; } *pwp = '\0'; /* Output the generated password, and the line if it is full. */ sprintf(v + strlen(v), "%*d) %s ", ndig, line, password); if ((++lineno) >= npline) { fprintf(ofile, "%s\n", v); v[0] = 0; lineno = 0; } /* If a signature file is being written, compute the MD5 signature of this item and append it to the signature file. */ if (sigfile != NULL) { int k; MD5Init(&md5c); MD5Update(&md5c, (unsigned char *) password, strlen(password)); MD5Final(digest, &md5c); for (k = 0; k < 16; k++) { fprintf(sigfile, "%02X", digest[k]); } fprintf(sigfile, "\n"); } } if (strlen(v) > 0) { fprintf(ofile, "%s\n", v); } fclose(ofile); return 0; } otp-1.2.2/random.c0000644000603300000120000003232612343164303013112 0ustar kelvinwheel/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include /* * random.c: * * An improved random number generation package. In addition to the standard * rand()/srand() like interface, this package also has a special state info * interface. The initstate() routine is called with a seed, an array of * bytes, and a count of how many bytes are being passed in; this array is * then initialized to contain information for random number generation with * that much state information. Good sizes for the amount of state * information are 32, 64, 128, and 256 bytes. The state can be switched by * calling the setstate() routine with the same array as was initiallized * with initstate(). By default, the package runs with 128 bytes of state * information and generates far better random numbers than a linear * congruential generator. If the amount of state information is less than * 32 bytes, a simple linear congruential R.N.G. is used. * * Internally, the state information is treated as an array of int32_ts; the * zeroeth element of the array is the type of R.N.G. being used (small * integer); the remainder of the array is the state information for the * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of * state information, which will allow a degree seven polynomial. (Note: * the zeroeth word of state information also has some other information * stored in it -- see setstate() for details). * * The random number generation technique is a linear feedback shift register * approach, employing trinomials (since there are fewer terms to sum up that * way). In this approach, the least significant bit of all the numbers in * the state table will act as a linear feedback shift register, and will * have period 2^deg - 1 (where deg is the degree of the polynomial being * used, assuming that the polynomial is irreducible and primitive). The * higher order bits will have longer periods, since their values are also * influenced by pseudo-random carries out of the lower bits. The total * period of the generator is approximately deg*(2**deg - 1); thus doubling * the amount of state information has a vast influence on the period of the * generator. Note: the deg*(2**deg - 1) is an approximation only good for * large deg, when the period of the shift register is the dominant factor. * With deg equal to seven, the period is actually much longer than the * 7*(2**7 - 1) predicted by this formula. */ /* * For each of the currently supported random number generators, we have a * break value on the amount of state information (you need at least this * many bytes of state info to support this random number generator), a degree * for the polynomial (actually a trinomial) that the R.N.G. is based on, and * the separation between the two lower order coefficients of the trinomial. */ #define TYPE_0 0 /* linear congruential */ #define BREAK_0 8 #define DEG_0 0 #define SEP_0 0 #define TYPE_1 1 /* x**7 + x**3 + 1 */ #define BREAK_1 32 #define DEG_1 7 #define SEP_1 3 #define TYPE_2 2 /* x**15 + x + 1 */ #define BREAK_2 64 #define DEG_2 15 #define SEP_2 1 #define TYPE_3 3 /* x**31 + x**3 + 1 */ #define BREAK_3 128 #define DEG_3 31 #define SEP_3 3 #define TYPE_4 4 /* x**63 + x + 1 */ #define BREAK_4 256 #define DEG_4 63 #define SEP_4 1 /* * Array versions of the above information to make code run faster -- * relies on fact that TYPE_i == i. */ #define MAX_TYPES 5 /* max number of types above */ static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; /* * Initially, everything is set up as if from: * * initstate(1, &randtbl, 128); * * Note that this initialization takes advantage of the fact that srandom() * advances the front and rear pointers 10*rand_deg times, and hence the * rear pointer which starts at 0 will also end up at zero; thus the zeroeth * element of the state information, which contains info about the current * position of the rear pointer is just * * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. */ static int32_t randtbl[DEG_3 + 1] = { TYPE_3, 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 0x27fb47b9, }; /* * fptr and rptr are two pointers into the state info, a front and a rear * pointer. These two pointers are always rand_sep places aparts, as they * cycle cyclically through the state information. (Yes, this does mean we * could get away with just one pointer, but the code for random() is more * efficient this way). The pointers are left positioned as they would be * from the call * * initstate(1, randtbl, 128); * * (The position of the rear pointer, rptr, is really 0 (as explained above * in the initialization of randtbl) because the state table pointer is set * to point to randtbl[1] (as explained below). */ static int32_t *fptr = &randtbl[SEP_3 + 1]; static int32_t *rptr = &randtbl[1]; /* * The following things are the pointer to the state information table, the * type of the current generator, the degree of the current polynomial being * used, and the separation between the two pointers. Note that for efficiency * of random(), we remember the first location of the state information, not * the zeroeth. Hence it is valid to access state[-1], which is used to * store the type of the R.N.G. Also, we remember the last location, since * this is more efficient than indexing every time to find the address of * the last element to see if the front and rear pointers have wrapped. */ static int32_t *state = &randtbl[1]; static int rand_type = TYPE_3; static int rand_deg = DEG_3; static int rand_sep = SEP_3; static int32_t *end_ptr = &randtbl[DEG_3 + 1]; /* * srandom: * * Initialize the random number generator based on the given seed. If the * type is the trivial no-state-information type, just remember the seed. * Otherwise, initializes state[] based on the given "seed" via a linear * congruential generator. Then, the pointers are set to known locations * that are exactly rand_sep places apart. Lastly, it cycles the state * information a given number of times to get rid of any initial dependencies * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] * for default usage relies on values produced by this routine. */ #define u_int uint32_t extern int32_t o_random(); void o_srandom(u_int x) { register int32_t i; #ifdef NEEDED if (rand_type == TYPE_0) state[0] = x; else { #endif /* NEEDED */ state[0] = x; for (i = 1; i < rand_deg; i++) state[i] = 1103515245 * state[i - 1] + 12345; fptr = &state[rand_sep]; rptr = &state[0]; for (i = 0; i < 10 * rand_deg; i++) (void)o_random(); #ifdef NEEDED } #endif /* NEEDED */ } /* * initstate: * * Initialize the state information in the given array of n bytes for future * random number generation. Based on the number of bytes we are given, and * the break values for the different R.N.G.'s, we choose the best (largest) * one we can and set things up for it. srandom() is then called to * initialize the state information. * * Note that on return from srandom(), we set state[-1] to be the type * multiplexed with the current value of the rear pointer; this is so * successive calls to initstate() won't lose this information and will be * able to restart with setstate(). * * Note: the first thing we do is save the current state, if any, just like * setstate() so that it doesn't matter when initstate is called. * * Returns a pointer to the old state. */ char * o_initstate(u_int seed, /* seed for R.N.G. */ char *arg_state, /* pointer to state array */ int n) /* # bytes of state info */ { register char *ostate = (char *)(&state[-1]); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES * (rptr - state) + rand_type; #ifdef NEEDED if (n < BREAK_0) { (void)fprintf(stderr, "random: not enough state (%d bytes); ignored.\n", n); return(0); } #endif /* NEEDED */ if (n < BREAK_1) { rand_type = TYPE_0; rand_deg = DEG_0; rand_sep = SEP_0; } else if (n < BREAK_2) { rand_type = TYPE_1; rand_deg = DEG_1; rand_sep = SEP_1; } else if (n < BREAK_3) { rand_type = TYPE_2; rand_deg = DEG_2; rand_sep = SEP_2; } else if (n < BREAK_4) { rand_type = TYPE_3; rand_deg = DEG_3; rand_sep = SEP_3; } else { rand_type = TYPE_4; rand_deg = DEG_4; rand_sep = SEP_4; } state = &(((int32_t *)arg_state)[1]); /* first location */ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ o_srandom(seed); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES*(rptr - state) + rand_type; return(ostate); } /* * setstate: * * Restore the state from the given state array. * * Note: it is important that we also remember the locations of the pointers * in the current state information, and restore the locations of the pointers * from the old state information. This is done by multiplexing the pointer * location into the zeroeth word of the state information. * * Note that due to the order in which things are done, it is OK to call * setstate() with the same state as the current state. * * Returns a pointer to the old state information. */ char * o_setstate(char *arg_state) { register int32_t *new_state = (int32_t *)arg_state; register int type = new_state[0] % MAX_TYPES; register int rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES * (rptr - state) + rand_type; switch(type) { case TYPE_0: case TYPE_1: case TYPE_2: case TYPE_3: case TYPE_4: rand_type = type; rand_deg = degrees[type]; rand_sep = seps[type]; break; default: #ifdef NEEDED (void)fprintf(stderr, "random: state info corrupted; not changed.\n"); #else exit(2); #endif /* NEEDED */ } state = &new_state[1]; if (rand_type != TYPE_0) { rptr = &state[rear]; fptr = &state[(rear + rand_sep) % rand_deg]; } end_ptr = &state[rand_deg]; /* set end_ptr too */ return(ostate); } /* * random: * * If we are using the trivial TYPE_0 R.N.G., just do the old linear * congruential bit. Otherwise, we do our fancy trinomial stuff, which is * the same in all the other cases due to all the global variables that have * been set up. The basic operation is to add the number at the rear pointer * into the one at the front pointer. Then both pointers are advanced to * the next location cyclically in the table. The value returned is the sum * generated, reduced to 31 bits by throwing away the "least random" low bit. * * Note: the code takes advantage of the fact that both the front and * rear pointers can't wrap on the same call by not testing the rear * pointer if the front one has wrapped. * * Returns a 31-bit random number. */ int32_t o_random(void) { int32_t i; #ifdef NEEDED if (rand_type == TYPE_0) i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; else { #endif *fptr += *rptr; i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */ if (++fptr >= end_ptr) { fptr = state; ++rptr; } else if (++rptr >= end_ptr) rptr = state; #ifdef NEEDED } #endif return(i); } otp-1.2.2/test.sh0000744000603300000120000000051110525627057013003 0ustar kelvinwheel#! /bin/sh ./otp -rTEST -n4 -mt1.md5 >test.out ./otp -rTEST -n3 -c12 -mt2.md5 >>test.out ./otp -rTEST -n3 -e12 -mt3.md5 >>test.out ./otp -rTEST -n4 -S5 -e -c -mt4.md5 >>test.out ./otp -rTEST -n7 -d4 -mt5.md5 >>test.out cat t1.md5 >>test.out cat t2.md5 >>test.out cat t3.md5 >>test.out cat t4.md5 >>test.out cat t5.md5 >>test.out otp-1.2.2/README0000644000603300000120000000057310526116174012351 0ustar kelvinwheel This program can be built on either MS-DOS/Windows or Unix. Because Windows development tools differ so much from one another, a ready-to-run OTP.EXE Win32 console application is included in this archive. It was compiled with Microsoft Visual C++ .7.0 / Visual Studio .NET. The "Onetime.sln" and "Onetime.vcproj" files used to build this version are included in the archive.