-- M. D. Schroeder, November 3, 1981 3:28 PM; -- DIRECTORY crD: FROM "CoreDefs", csD: FROM "CoreStreamDefs", DESDefs, IODefs, Inline, ovD: FROM "OverviewDefs", Storage, String, Stream, Time; CryptFile: PROGRAM IMPORTS csD, DESDefs, Inline, IODefs, Storage, String, Time = BEGIN OPEN IODefs; user: crD.DMSUser = [NIL, NIL, NIL]; key: DESDefs.Key; seed: DESDefs.Block; modeChar: CHARACTER; s: STRING _ [64]; inputHandle: csD.StreamHandle _ NIL; outputHandle: csD.StreamHandle _ NIL; deadBytes: [0 .. 255]; bufferPages: CARDINAL = 2; bP: POINTER = Storage.Pages[bufferPages]; inStreamPages: CARDINAL = 1; outStreamPages: CARDINAL = 1; time: LONG CARDINAL; length, bytesRead: csD.Position; xString: STRING = "XXX "L; unexpectedString: STRING = "***Unexpected disk error***"L; DescribeOpenError: PROCEDURE [r: ovD.ErrorCode] = BEGIN SELECT r FROM ovD.illegalFilename => WriteLine["***File name illegal***"L]; ovD.fileInUse => WriteLine["***File in use***"L]; ovD.fileNotFound => WriteLine["***File not found***"L]; ENDCASE => WriteLine[unexpectedString]; END; --DescribeOpenError-- DescribeRWError: PROCEDURE [r: ovD.ErrorCode] = BEGIN WriteChar[CR]; SELECT r FROM ovD.diskFull => WriteLine["***Disk full***"L]; ovD.fileTooBig => WriteLine["***File too big***"L]; ovD.diskError, ovD.diskCorrupted => WriteLine["***Disk error***"L]; ENDCASE => WriteLine[unexpectedString]; WriteLine["Trying to delete output file."L]; csD.Reset[outputHandle ! csD.Error => CONTINUE]; END; --DescribeRWError-- DO -- main command loop -- BEGIN -- block for exits -- WriteString["Type e for encrypt; d for decrypt; q for quit: "L]; DO SELECT modeChar _ ReadChar[] FROM 'd, 'e, 'q => {WriteChar[modeChar]; EXIT}; ENDCASE => {WriteChar['?]; LOOP}; ENDLOOP; WriteChar[CR]; IF modeChar = 'q THEN EXIT; s.length _ 0; WriteString["Type input file name: "L]; ReadLine[s ! Rubout => {WriteString[xString]; RETRY}]; inputHandle _ csD.OpenFromName[s, user, byte, read, inStreamPages ! csD.Error => {DescribeOpenError[reason]; GOTO finish}]; s.length _ 0; WriteString["Type output file name: "L]; ReadLine[s ! Rubout => {WriteString[xString]; RETRY}]; outputHandle _ csD.OpenFromName[s, user, byte, overwrite, outStreamPages ! csD.Error => {DescribeOpenError[reason]; GOTO finish}]; s.length _ 0; WriteString["Type key string: "L]; ReadLine[s ! Rubout => {WriteString[xString]; RETRY}]; key _ DESDefs.MakeKey[LONG[s]]; seed _ LOOPHOLE[key, DESDefs.Block]; time _ Time.Current[]; length _ csD.GetLength[inputHandle]; IF modeChar='e THEN BEGIN --encrypting, so save number of dead bytes at the start of the file-- deadBytes _ (8 - Inline.LowHalf[length MOD 8]) MOD 8; csD.Write[outputHandle, deadBytes ! csD.Error=>{DescribeRWError[reason]; GOTO finish} ]; bytesRead _ 0; END ELSE BEGIN --retrieve dead bytes number-- deadBytes _ csD.Read[inputHandle ! csD.Error=>{DescribeRWError[reason]; GOTO finish}]; IF deadBytes > 7 THEN {WriteLine["Input file not encrypted."L]; GOTO finish}; bytesRead _ 1; END; WriteString[" ..."L]; UNTIL bytesRead=length DO nBytes: CARDINAL = csD.ReadBlock[inputHandle, bP, 0, bufferPages*512 ! csD.Error=>{DescribeRWError[reason]; GOTO finish}]; nBlocks: CARDINAL = (nBytes+7)/8; writeBytes: CARDINAL _ nBlocks*8; bytesRead _ bytesRead+nBytes; IF bytesRead=length AND modeChar='d THEN writeBytes_writeBytes-deadBytes; seed _ IF modeChar='e THEN DESDefs.CBCEncrypt[key, seed, nBlocks, LONG[bP], LONG[bP]] ELSE DESDefs.CBCDecrypt[key, seed, nBlocks, LONG[bP], LONG[bP]]; csD.WriteBlock[outputHandle, bP, 0, writeBytes ! csD.Error=>{DescribeRWError[reason]; GOTO finish}]; WriteChar['.]; ENDLOOP; WriteChar[SP]; csD.Checkpoint[outputHandle]; time _ Time.Current[] - time; IF modeChar = 'd THEN length _ length - deadBytes - 1; s.length _ 0; String.AppendLongDecimal[s, LOOPHOLE[length, LONG INTEGER]]; WriteString[s]; WriteString[" byte file "L]; WriteString[IF modeChar='e THEN "en"L ELSE "de"L]; WriteString["crypted"L]; IF length > 512 THEN BEGIN WriteString[" at the rate of "L]; WriteDecimal[LOOPHOLE[Inline.LowHalf[length/time], INTEGER]]; WriteString[" bytes per second"L]; END; WriteLine["."L]; GOTO finish; EXITS finish => BEGIN IF inputHandle#NIL THEN {csD.Destroy[inputHandle]; inputHandle _ NIL}; IF outputHandle#NIL THEN {csD.Destroy[outputHandle]; outputHandle _ NIL}; END; END; -- exits block -- WriteChar[CR]; ENDLOOP; -- main command loop -- Storage.FreePages[bP]; END. --CryptFile program-- (635)\f1