1implement Idea; 2 3# 4# Copyright © 2002 Vita Nuova Holdings Limited. All rights reserved. 5# 6 7include "sys.m"; 8 sys: Sys; 9include "draw.m"; 10include "bufio.m"; 11 bufio: Bufio; 12 Iobuf: import bufio; 13include "keyring.m"; 14 keyring: Keyring; 15 16Idea: module 17{ 18 init: fn(nil: ref Draw->Context, argv: list of string); 19}; 20 21decerr(s: string) 22{ 23 sys->fprint(sys->fildes(2), "decrypt error: %s (wrong password ?)\n", s); 24 exit; 25} 26 27init(nil: ref Draw->Context, argv: list of string) 28{ 29 sys = load Sys Sys->PATH; 30 stdin := sys->fildes(0); 31 stdout := sys->fildes(1); 32 33 bufio = load Bufio Bufio->PATH; 34 keyring = load Keyring Keyring->PATH; 35 36 obuf := array[8] of byte; 37 buf := array[8] of byte; 38 key := array[16] of byte; 39 40 argc := len argv; 41 if((argc != 3 && argc != 4) || (hd tl argv != "-e" && hd tl argv != "-d") || len hd tl tl argv != 16){ 42 sys->fprint(sys->fildes(2), "usage: idea -[e | d] <16 char key> [inputfile]\n"); 43 exit; 44 } 45 dec := hd tl argv == "-d"; 46 if(argc == 4){ 47 s := hd tl tl tl argv; 48 stdin = sys->open(s, Sys->OREAD); 49 if(stdin == nil){ 50 sys->fprint(sys->fildes(2), "cannot open %s\n", s); 51 exit; 52 } 53 if(dec){ 54 l := len s; 55 if(s[l-3: l] != ".id"){ 56 sys->fprint(sys->fildes(2), "input file not a .id file\n"); 57 exit; 58 } 59 s = s[0: l-3]; 60 } 61 else 62 s += ".id"; 63 stdout = sys->create(s, Sys->OWRITE, 8r666); 64 if(stdout == nil){ 65 sys->fprint(sys->fildes(2), "cannot create %s\n", s); 66 exit; 67 } 68 } 69 for(i := 0; i < 16; i++) 70 key[i] = byte (hd tl tl argv)[i]; 71 is := keyring->ideasetup(key, nil); 72 m := om := 0; 73 bin := bufio->fopen(stdin, Bufio->OREAD); 74 bout := bufio->fopen(stdout, Bufio->OWRITE); 75 for(;;){ 76 n := bin.read(buf[m: ], 8-m); 77 if(n <= 0) 78 break; 79 m += n; 80 if(m == 8){ 81 keyring->ideaecb(is, buf, 8, dec); 82 if(dec){ # leave last block around 83 if(om > 0) 84 bout.write(obuf, 8); 85 obuf[0: ] = buf[0: 8]; 86 om = 8; 87 } 88 else 89 bout.write(buf, 8); 90 m = 0; 91 } 92 } 93 if(dec){ 94 if(om != 8) 95 decerr("no last block"); 96 if(m != 0) 97 decerr("last block not 8 bytes long"); 98 m = int obuf[7]; 99 if(m < 0 || m > 7) 100 decerr("bad modulus"); 101 for(i = m; i < 8-1; i++) 102 if(obuf[i] != byte 0) 103 decerr("byte not 0"); 104 bout.write(obuf, m); 105 } 106 else{ 107 for(i = m; i < 8; i++) 108 buf[i] = byte 0; 109 buf[7] = byte m; 110 keyring->ideaecb(is, buf, 8, dec); 111 bout.write(buf, 8); 112 } 113 bout.flush(); 114 bin.close(); 115 bout.close(); 116} 117