Blame


1 7d3bbe16 2004-04-21 devnull /* encrypt file by writing
2 7d3bbe16 2004-04-21 devnull v2hdr,
3 7d3bbe16 2004-04-21 devnull 16byte initialization vector,
4 7d3bbe16 2004-04-21 devnull AES-CBC(key, random | file),
5 7d3bbe16 2004-04-21 devnull HMAC_SHA1(md5(key), AES-CBC(random | file))
6 7d3bbe16 2004-04-21 devnull
7 7d3bbe16 2004-04-21 devnull With CBC, if the first plaintext block is 0, the first ciphertext block is
8 7d3bbe16 2004-04-21 devnull E(IV). Using the overflow technique adopted for compatibility with cryptolib
9 7d3bbe16 2004-04-21 devnull makes the last cipertext block decryptable. Hence the random prefix to file.
10 7d3bbe16 2004-04-21 devnull */
11 7d3bbe16 2004-04-21 devnull #include <u.h>
12 7d3bbe16 2004-04-21 devnull #include <libc.h>
13 7d3bbe16 2004-04-21 devnull #include <bio.h>
14 7d3bbe16 2004-04-21 devnull #include <mp.h>
15 7d3bbe16 2004-04-21 devnull #include <libsec.h>
16 7d3bbe16 2004-04-21 devnull
17 7d3bbe16 2004-04-21 devnull enum{ CHK = 16, BUF = 4096 };
18 7d3bbe16 2004-04-21 devnull
19 7d3bbe16 2004-04-21 devnull uchar v2hdr[AESbsize+1] = "AES CBC SHA1 2\n";
20 7d3bbe16 2004-04-21 devnull Biobuf bin;
21 7d3bbe16 2004-04-21 devnull Biobuf bout;
22 7d3bbe16 2004-04-21 devnull
23 7d3bbe16 2004-04-21 devnull void
24 7d3bbe16 2004-04-21 devnull safewrite(uchar *buf, int n)
25 7d3bbe16 2004-04-21 devnull {
26 7d3bbe16 2004-04-21 devnull int i = Bwrite(&bout, buf, n);
27 7d3bbe16 2004-04-21 devnull
28 7d3bbe16 2004-04-21 devnull if(i == n)
29 7d3bbe16 2004-04-21 devnull return;
30 7d3bbe16 2004-04-21 devnull fprint(2, "write error\n");
31 7d3bbe16 2004-04-21 devnull exits("write error");
32 7d3bbe16 2004-04-21 devnull }
33 7d3bbe16 2004-04-21 devnull
34 7d3bbe16 2004-04-21 devnull void
35 7d3bbe16 2004-04-21 devnull saferead(uchar *buf, int n)
36 7d3bbe16 2004-04-21 devnull {
37 7d3bbe16 2004-04-21 devnull int i = Bread(&bin, buf, n);
38 7d3bbe16 2004-04-21 devnull
39 7d3bbe16 2004-04-21 devnull if(i == n)
40 7d3bbe16 2004-04-21 devnull return;
41 7d3bbe16 2004-04-21 devnull fprint(2, "read error\n");
42 7d3bbe16 2004-04-21 devnull exits("read error");
43 7d3bbe16 2004-04-21 devnull }
44 7d3bbe16 2004-04-21 devnull
45 7d3bbe16 2004-04-21 devnull int
46 7d3bbe16 2004-04-21 devnull main(int argc, char **argv)
47 7d3bbe16 2004-04-21 devnull {
48 7d3bbe16 2004-04-21 devnull int encrypt = 0; /* 0=decrypt, 1=encrypt */
49 7d3bbe16 2004-04-21 devnull int n, nkey;
50 7d3bbe16 2004-04-21 devnull char *hex, *msg = nil;
51 7d3bbe16 2004-04-21 devnull uchar key[AESmaxkey], key2[MD5dlen];
52 7d3bbe16 2004-04-21 devnull uchar buf[BUF+SHA1dlen]; /* assumption: CHK <= SHA1dlen */
53 7d3bbe16 2004-04-21 devnull AESstate aes;
54 7d3bbe16 2004-04-21 devnull DigestState *dstate;
55 7d3bbe16 2004-04-21 devnull
56 7d3bbe16 2004-04-21 devnull if(argc!=2 || argv[1][0]!='-'){
57 7d3bbe16 2004-04-21 devnull fprint(2,"usage: HEX=key %s -d < cipher.aes > clear.txt\n", argv[0]);
58 7d3bbe16 2004-04-21 devnull fprint(2," or: HEX=key %s -e < clear.txt > cipher.aes\n", argv[0]);
59 7d3bbe16 2004-04-21 devnull exits("usage");
60 7d3bbe16 2004-04-21 devnull }
61 7d3bbe16 2004-04-21 devnull if(argv[1][1] == 'e')
62 7d3bbe16 2004-04-21 devnull encrypt = 1;
63 7d3bbe16 2004-04-21 devnull Binit(&bin, 0, OREAD);
64 7d3bbe16 2004-04-21 devnull Binit(&bout, 1, OWRITE);
65 7d3bbe16 2004-04-21 devnull
66 7d3bbe16 2004-04-21 devnull if((hex = getenv("HEX")) == nil)
67 7d3bbe16 2004-04-21 devnull hex = getpass("enter key: ");
68 7d3bbe16 2004-04-21 devnull nkey = 0;
69 7d3bbe16 2004-04-21 devnull if(hex != nil)
70 7d3bbe16 2004-04-21 devnull nkey = strlen(hex);
71 7d3bbe16 2004-04-21 devnull if(nkey == 0 || (nkey&1) || nkey>2*AESmaxkey){
72 7d3bbe16 2004-04-21 devnull fprint(2,"key should be 32 hex digits\n");
73 7d3bbe16 2004-04-21 devnull exits("key");
74 7d3bbe16 2004-04-21 devnull }
75 7d3bbe16 2004-04-21 devnull nkey = dec16(key, sizeof key, hex, nkey);
76 7d3bbe16 2004-04-21 devnull md5(key, nkey, key2, 0); /* so even if HMAC_SHA1 is broken, encryption key is protected */
77 7d3bbe16 2004-04-21 devnull
78 7d3bbe16 2004-04-21 devnull if(encrypt){
79 7d3bbe16 2004-04-21 devnull safewrite(v2hdr, AESbsize);
80 7d3bbe16 2004-04-21 devnull genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
81 7d3bbe16 2004-04-21 devnull setupAESstate(&aes, key, nkey, buf); /* use first AESbsize bytes as IV */
82 7d3bbe16 2004-04-21 devnull aesCBCencrypt(buf+AESbsize, AESbsize, &aes); /* use second AESbsize bytes as initial plaintext */
83 7d3bbe16 2004-04-21 devnull safewrite(buf, 2*AESbsize);
84 7d3bbe16 2004-04-21 devnull dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
85 7d3bbe16 2004-04-21 devnull while(1){
86 7d3bbe16 2004-04-21 devnull n = Bread(&bin, buf, BUF);
87 7d3bbe16 2004-04-21 devnull if(n < 0){
88 7d3bbe16 2004-04-21 devnull msg = "read error";
89 7d3bbe16 2004-04-21 devnull goto Exit;
90 7d3bbe16 2004-04-21 devnull }
91 7d3bbe16 2004-04-21 devnull aesCBCencrypt(buf, n, &aes);
92 7d3bbe16 2004-04-21 devnull safewrite(buf, n);
93 7d3bbe16 2004-04-21 devnull dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
94 7d3bbe16 2004-04-21 devnull if(n < BUF)
95 7d3bbe16 2004-04-21 devnull break; /* EOF */
96 7d3bbe16 2004-04-21 devnull }
97 7d3bbe16 2004-04-21 devnull hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
98 7d3bbe16 2004-04-21 devnull safewrite(buf, SHA1dlen);
99 7d3bbe16 2004-04-21 devnull }else{ /* decrypt */
100 7d3bbe16 2004-04-21 devnull Bread(&bin, buf, AESbsize);
101 7d3bbe16 2004-04-21 devnull if(memcmp(buf, v2hdr, AESbsize) == 0){
102 7d3bbe16 2004-04-21 devnull saferead(buf, 2*AESbsize); /* read IV and random initial plaintext */
103 7d3bbe16 2004-04-21 devnull setupAESstate(&aes, key, nkey, buf);
104 7d3bbe16 2004-04-21 devnull dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
105 7d3bbe16 2004-04-21 devnull aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
106 7d3bbe16 2004-04-21 devnull saferead(buf, SHA1dlen);
107 7d3bbe16 2004-04-21 devnull while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
108 7d3bbe16 2004-04-21 devnull dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
109 7d3bbe16 2004-04-21 devnull aesCBCdecrypt(buf, n, &aes);
110 7d3bbe16 2004-04-21 devnull safewrite(buf, n);
111 7d3bbe16 2004-04-21 devnull memmove(buf, buf+n, SHA1dlen); /* these bytes are not yet decrypted */
112 7d3bbe16 2004-04-21 devnull }
113 7d3bbe16 2004-04-21 devnull hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
114 7d3bbe16 2004-04-21 devnull if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0){
115 7d3bbe16 2004-04-21 devnull msg = "decrypted file failed to authenticate!";
116 7d3bbe16 2004-04-21 devnull goto Exit;
117 7d3bbe16 2004-04-21 devnull }
118 7d3bbe16 2004-04-21 devnull }else{ /* compatibility with past mistake */
119 7d3bbe16 2004-04-21 devnull // if file was encrypted with bad aescbc use this:
120 7d3bbe16 2004-04-21 devnull // memset(key, 0, AESmaxkey);
121 7d3bbe16 2004-04-21 devnull // else assume we're decrypting secstore files
122 7d3bbe16 2004-04-21 devnull setupAESstate(&aes, key, 0, buf);
123 7d3bbe16 2004-04-21 devnull saferead(buf, CHK);
124 7d3bbe16 2004-04-21 devnull aesCBCdecrypt(buf, CHK, &aes);
125 7d3bbe16 2004-04-21 devnull while((n = Bread(&bin, buf+CHK, BUF)) > 0){
126 7d3bbe16 2004-04-21 devnull aesCBCdecrypt(buf+CHK, n, &aes);
127 7d3bbe16 2004-04-21 devnull safewrite(buf, n);
128 7d3bbe16 2004-04-21 devnull memmove(buf, buf+n, CHK);
129 7d3bbe16 2004-04-21 devnull }
130 7d3bbe16 2004-04-21 devnull if(memcmp(buf, "XXXXXXXXXXXXXXXX", CHK) != 0){
131 7d3bbe16 2004-04-21 devnull msg = "decrypted file failed to authenticate";
132 7d3bbe16 2004-04-21 devnull goto Exit;
133 7d3bbe16 2004-04-21 devnull }
134 7d3bbe16 2004-04-21 devnull }
135 7d3bbe16 2004-04-21 devnull }
136 7d3bbe16 2004-04-21 devnull Exit:
137 7d3bbe16 2004-04-21 devnull memset(key, 0, sizeof(key));
138 7d3bbe16 2004-04-21 devnull memset(key2, 0, sizeof(key2));
139 7d3bbe16 2004-04-21 devnull memset(buf, 0, sizeof(buf));
140 7d3bbe16 2004-04-21 devnull if(msg != nil)
141 7d3bbe16 2004-04-21 devnull fprint(2, "%s\n", msg);
142 7d3bbe16 2004-04-21 devnull exits(msg);
143 7d3bbe16 2004-04-21 devnull return 1; /* gcc */
144 7d3bbe16 2004-04-21 devnull }