Don't build lex until Russ says it is OK (it is useful for troff, which I don't really want to port to flex).
Add aescbc because I use it once in a while.
diff --git a/src/cmd/aescbc.c b/src/cmd/aescbc.c
new file mode 100644
index 0000000..9f4bfff
--- /dev/null
+++ b/src/cmd/aescbc.c
@@ -0,0 +1,144 @@
+/* encrypt file by writing
+	v2hdr,
+	16byte initialization vector,
+	AES-CBC(key, random | file),
+    HMAC_SHA1(md5(key), AES-CBC(random | file))
+
+With CBC, if the first plaintext block is 0, the first ciphertext block is
+E(IV).  Using the overflow technique adopted for compatibility with cryptolib
+makes the last cipertext block decryptable.  Hence the random prefix to file.
+*/
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mp.h>
+#include <libsec.h>
+
+enum{ CHK = 16, BUF = 4096 };
+
+uchar v2hdr[AESbsize+1] = "AES CBC SHA1  2\n";
+Biobuf bin;
+Biobuf bout;
+
+void
+safewrite(uchar *buf, int n)
+{
+	int i = Bwrite(&bout, buf, n);
+
+	if(i == n)
+		return;
+	fprint(2, "write error\n");
+	exits("write error");
+}
+
+void
+saferead(uchar *buf, int n)
+{
+	int i = Bread(&bin, buf, n);
+
+	if(i == n)
+		return;
+	fprint(2, "read error\n");
+	exits("read error");
+}
+
+int
+main(int argc, char **argv)
+{
+	int encrypt = 0;  /* 0=decrypt, 1=encrypt */
+	int n, nkey;
+	char *hex, *msg = nil;
+	uchar key[AESmaxkey], key2[MD5dlen];
+	uchar buf[BUF+SHA1dlen];    /* assumption: CHK <= SHA1dlen */
+	AESstate aes;
+	DigestState *dstate;
+
+	if(argc!=2 || argv[1][0]!='-'){
+		fprint(2,"usage: HEX=key %s -d < cipher.aes > clear.txt\n", argv[0]);
+		fprint(2,"   or: HEX=key %s -e < clear.txt > cipher.aes\n", argv[0]);
+		exits("usage");
+	}
+	if(argv[1][1] == 'e')
+		encrypt = 1;
+	Binit(&bin, 0, OREAD);
+	Binit(&bout, 1, OWRITE);
+
+	if((hex = getenv("HEX")) == nil)
+		hex = getpass("enter key: ");
+	nkey = 0;
+	if(hex != nil)
+		nkey = strlen(hex);
+	if(nkey == 0 || (nkey&1) || nkey>2*AESmaxkey){
+		fprint(2,"key should be 32 hex digits\n");
+		exits("key");
+	}
+	nkey = dec16(key, sizeof key, hex, nkey);
+	md5(key, nkey, key2, 0);  /* so even if HMAC_SHA1 is broken, encryption key is protected */
+
+	if(encrypt){
+		safewrite(v2hdr, AESbsize);
+		genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
+		setupAESstate(&aes, key, nkey, buf);  /* use first AESbsize bytes as IV */
+		aesCBCencrypt(buf+AESbsize, AESbsize, &aes);  /* use second AESbsize bytes as initial plaintext */
+		safewrite(buf, 2*AESbsize);
+		dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
+		while(1){
+			n = Bread(&bin, buf, BUF);
+			if(n < 0){
+				msg = "read error";
+				goto Exit;
+			}
+			aesCBCencrypt(buf, n, &aes);
+			safewrite(buf, n);
+			dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
+			if(n < BUF)
+				break; /* EOF */
+		}
+		hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
+		safewrite(buf, SHA1dlen);
+	}else{ /* decrypt */
+		Bread(&bin, buf, AESbsize);
+		if(memcmp(buf, v2hdr, AESbsize) == 0){
+			saferead(buf, 2*AESbsize);  /* read IV and random initial plaintext */
+			setupAESstate(&aes, key, nkey, buf);
+			dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
+			aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
+			saferead(buf, SHA1dlen);
+			while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
+				dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
+				aesCBCdecrypt(buf, n, &aes);
+				safewrite(buf, n);
+				memmove(buf, buf+n, SHA1dlen);  /* these bytes are not yet decrypted */
+			}
+			hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
+			if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0){
+				msg = "decrypted file failed to authenticate!";
+				goto Exit;
+			}
+		}else{ /* compatibility with past mistake */
+			// if file was encrypted with bad aescbc use this:
+			//         memset(key, 0, AESmaxkey);
+			//    else assume we're decrypting secstore files
+			setupAESstate(&aes, key, 0, buf);
+			saferead(buf, CHK);
+			aesCBCdecrypt(buf, CHK, &aes);
+			while((n = Bread(&bin, buf+CHK, BUF)) > 0){
+				aesCBCdecrypt(buf+CHK, n, &aes);
+				safewrite(buf, n);
+				memmove(buf, buf+n, CHK);
+			}
+			if(memcmp(buf, "XXXXXXXXXXXXXXXX", CHK) != 0){
+				msg = "decrypted file failed to authenticate";
+				goto Exit;
+			}
+		}
+	}
+ Exit:
+	memset(key, 0, sizeof(key));
+	memset(key2, 0, sizeof(key2));
+	memset(buf, 0, sizeof(buf));
+	if(msg != nil)
+		fprint(2, "%s\n", msg);
+	exits(msg);
+	return 1;	/* gcc */
+}