Blame


1 e80159c9 2011-12-07 rsc /*
2 e80159c9 2011-12-07 rsc encrypt file by writing
3 6e527fbc 2005-02-13 devnull v2hdr,
4 6e527fbc 2005-02-13 devnull 16byte initialization vector,
5 6e527fbc 2005-02-13 devnull AES-CBC(key, random | file),
6 e80159c9 2011-12-07 rsc HMAC_SHA1(md5(key), AES-CBC(random | file))
7 6e527fbc 2005-02-13 devnull */
8 6e527fbc 2005-02-13 devnull #include <u.h>
9 6e527fbc 2005-02-13 devnull #include <libc.h>
10 6e527fbc 2005-02-13 devnull #include <bio.h>
11 6e527fbc 2005-02-13 devnull #include <mp.h>
12 6e527fbc 2005-02-13 devnull #include <libsec.h>
13 6e527fbc 2005-02-13 devnull
14 6e527fbc 2005-02-13 devnull extern char* getpassm(char*);
15 6e527fbc 2005-02-13 devnull
16 6e527fbc 2005-02-13 devnull enum{ CHK = 16, BUF = 4096 };
17 6e527fbc 2005-02-13 devnull
18 6e527fbc 2005-02-13 devnull uchar v2hdr[AESbsize+1] = "AES CBC SHA1 2\n";
19 6e527fbc 2005-02-13 devnull Biobuf bin;
20 6e527fbc 2005-02-13 devnull Biobuf bout;
21 6e527fbc 2005-02-13 devnull
22 6e527fbc 2005-02-13 devnull void
23 6e527fbc 2005-02-13 devnull safewrite(uchar *buf, int n)
24 6e527fbc 2005-02-13 devnull {
25 6e527fbc 2005-02-13 devnull int i = Bwrite(&bout, buf, n);
26 6e527fbc 2005-02-13 devnull
27 6e527fbc 2005-02-13 devnull if(i == n)
28 6e527fbc 2005-02-13 devnull return;
29 6e527fbc 2005-02-13 devnull fprint(2, "write error\n");
30 6e527fbc 2005-02-13 devnull exits("write error");
31 6e527fbc 2005-02-13 devnull }
32 6e527fbc 2005-02-13 devnull
33 6e527fbc 2005-02-13 devnull void
34 6e527fbc 2005-02-13 devnull saferead(uchar *buf, int n)
35 6e527fbc 2005-02-13 devnull {
36 6e527fbc 2005-02-13 devnull int i = Bread(&bin, buf, n);
37 6e527fbc 2005-02-13 devnull
38 6e527fbc 2005-02-13 devnull if(i == n)
39 6e527fbc 2005-02-13 devnull return;
40 6e527fbc 2005-02-13 devnull fprint(2, "read error\n");
41 6e527fbc 2005-02-13 devnull exits("read error");
42 6e527fbc 2005-02-13 devnull }
43 6e527fbc 2005-02-13 devnull
44 35625b3f 2010-02-23 rsc uchar *copy;
45 35625b3f 2010-02-23 rsc int ncopy;
46 35625b3f 2010-02-23 rsc
47 35625b3f 2010-02-23 rsc void
48 35625b3f 2010-02-23 rsc safecopy(uchar *buf, int n)
49 35625b3f 2010-02-23 rsc {
50 35625b3f 2010-02-23 rsc copy = realloc(copy, ncopy+n);
51 35625b3f 2010-02-23 rsc if(copy == nil) {
52 35625b3f 2010-02-23 rsc fprint(2, "out of memory\n");
53 35625b3f 2010-02-23 rsc exits("memory");
54 35625b3f 2010-02-23 rsc }
55 35625b3f 2010-02-23 rsc memmove(copy+ncopy, buf, n);
56 35625b3f 2010-02-23 rsc ncopy += n;
57 35625b3f 2010-02-23 rsc }
58 35625b3f 2010-02-23 rsc
59 6e527fbc 2005-02-13 devnull int
60 6e527fbc 2005-02-13 devnull main(int argc, char **argv)
61 6e527fbc 2005-02-13 devnull {
62 6e527fbc 2005-02-13 devnull int encrypt = 0; /* 0=decrypt, 1=encrypt */
63 6e527fbc 2005-02-13 devnull int n, nkey, pass_stdin = 0;
64 6e527fbc 2005-02-13 devnull char *pass;
65 6e527fbc 2005-02-13 devnull uchar key[AESmaxkey], key2[SHA1dlen];
66 6e527fbc 2005-02-13 devnull uchar buf[BUF+SHA1dlen]; /* assumption: CHK <= SHA1dlen */
67 6e527fbc 2005-02-13 devnull AESstate aes;
68 6e527fbc 2005-02-13 devnull DigestState *dstate;
69 6e527fbc 2005-02-13 devnull
70 6e527fbc 2005-02-13 devnull ARGBEGIN{
71 6e527fbc 2005-02-13 devnull case 'e':
72 6e527fbc 2005-02-13 devnull encrypt = 1;
73 6e527fbc 2005-02-13 devnull break;
74 6e527fbc 2005-02-13 devnull case 'i':
75 6e527fbc 2005-02-13 devnull pass_stdin = 1;
76 6e527fbc 2005-02-13 devnull break;
77 6e527fbc 2005-02-13 devnull }ARGEND;
78 6e527fbc 2005-02-13 devnull if(argc!=0){
79 6e527fbc 2005-02-13 devnull fprint(2,"usage: %s -d < cipher.aes > clear.txt\n", argv0);
80 6e527fbc 2005-02-13 devnull fprint(2," or: %s -e < clear.txt > cipher.aes\n", argv0);
81 6e527fbc 2005-02-13 devnull exits("usage");
82 6e527fbc 2005-02-13 devnull }
83 6e527fbc 2005-02-13 devnull Binit(&bin, 0, OREAD);
84 6e527fbc 2005-02-13 devnull Binit(&bout, 1, OWRITE);
85 6e527fbc 2005-02-13 devnull
86 6e527fbc 2005-02-13 devnull if(pass_stdin){
87 6e527fbc 2005-02-13 devnull n = readn(3, buf, (sizeof buf)-1);
88 6e527fbc 2005-02-13 devnull if(n < 1)
89 6e527fbc 2005-02-13 devnull exits("usage: echo password |[3=1] auth/aescbc -i ...");
90 6e527fbc 2005-02-13 devnull buf[n] = 0;
91 6e527fbc 2005-02-13 devnull while(buf[n-1] == '\n')
92 6e527fbc 2005-02-13 devnull buf[--n] = 0;
93 6e527fbc 2005-02-13 devnull }else{
94 c5d1b221 2011-10-05 rsc pass = readcons("aescbc password", nil, 1);
95 e80159c9 2011-12-07 rsc if(pass == nil)
96 e80159c9 2011-12-07 rsc exits("readcons");
97 6e527fbc 2005-02-13 devnull n = strlen(pass);
98 6e527fbc 2005-02-13 devnull if(n >= BUF)
99 6e527fbc 2005-02-13 devnull exits("key too long");
100 6e527fbc 2005-02-13 devnull strcpy((char*)buf, pass);
101 6e527fbc 2005-02-13 devnull memset(pass, 0, n);
102 6e527fbc 2005-02-13 devnull free(pass);
103 6e527fbc 2005-02-13 devnull }
104 6e527fbc 2005-02-13 devnull if(n <= 0){
105 6e527fbc 2005-02-13 devnull fprint(2,"no key\n");
106 6e527fbc 2005-02-13 devnull exits("key");
107 6e527fbc 2005-02-13 devnull }
108 6e527fbc 2005-02-13 devnull dstate = sha1((uchar*)"aescbc file", 11, nil, nil);
109 6e527fbc 2005-02-13 devnull sha1(buf, n, key2, dstate);
110 6e527fbc 2005-02-13 devnull memcpy(key, key2, 16);
111 6e527fbc 2005-02-13 devnull nkey = 16;
112 6e527fbc 2005-02-13 devnull md5(key, nkey, key2, 0); /* so even if HMAC_SHA1 is broken, encryption key is protected */
113 6e527fbc 2005-02-13 devnull
114 6e527fbc 2005-02-13 devnull if(encrypt){
115 6e527fbc 2005-02-13 devnull safewrite(v2hdr, AESbsize);
116 6e527fbc 2005-02-13 devnull genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
117 6e527fbc 2005-02-13 devnull setupAESstate(&aes, key, nkey, buf); /* use first AESbsize bytes as IV */
118 6e527fbc 2005-02-13 devnull aesCBCencrypt(buf+AESbsize, AESbsize, &aes); /* use second AESbsize bytes as initial plaintext */
119 6e527fbc 2005-02-13 devnull safewrite(buf, 2*AESbsize);
120 6e527fbc 2005-02-13 devnull dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
121 cbeb0b26 2006-04-01 devnull for(;;){
122 6e527fbc 2005-02-13 devnull n = Bread(&bin, buf, BUF);
123 6e527fbc 2005-02-13 devnull if(n < 0){
124 6e527fbc 2005-02-13 devnull fprint(2,"read error\n");
125 6e527fbc 2005-02-13 devnull exits("read error");
126 6e527fbc 2005-02-13 devnull }
127 6e527fbc 2005-02-13 devnull aesCBCencrypt(buf, n, &aes);
128 6e527fbc 2005-02-13 devnull safewrite(buf, n);
129 6e527fbc 2005-02-13 devnull dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
130 6e527fbc 2005-02-13 devnull if(n < BUF)
131 6e527fbc 2005-02-13 devnull break; /* EOF */
132 6e527fbc 2005-02-13 devnull }
133 6e527fbc 2005-02-13 devnull hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
134 6e527fbc 2005-02-13 devnull safewrite(buf, SHA1dlen);
135 6e527fbc 2005-02-13 devnull }else{ /* decrypt */
136 6e527fbc 2005-02-13 devnull saferead(buf, AESbsize);
137 35625b3f 2010-02-23 rsc if(memcmp(buf, v2hdr, AESbsize) != 0){
138 35625b3f 2010-02-23 rsc fprint(2, "not an aescbc file\n");
139 35625b3f 2010-02-23 rsc exits("aescbc file");
140 6e527fbc 2005-02-13 devnull }
141 35625b3f 2010-02-23 rsc saferead(buf, 2*AESbsize); /* read IV and random initial plaintext */
142 35625b3f 2010-02-23 rsc setupAESstate(&aes, key, nkey, buf);
143 35625b3f 2010-02-23 rsc dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
144 35625b3f 2010-02-23 rsc aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
145 35625b3f 2010-02-23 rsc saferead(buf, SHA1dlen);
146 35625b3f 2010-02-23 rsc while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
147 35625b3f 2010-02-23 rsc dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
148 35625b3f 2010-02-23 rsc aesCBCdecrypt(buf, n, &aes);
149 35625b3f 2010-02-23 rsc safecopy(buf, n);
150 35625b3f 2010-02-23 rsc memmove(buf, buf+n, SHA1dlen); /* these bytes are not yet decrypted */
151 35625b3f 2010-02-23 rsc }
152 35625b3f 2010-02-23 rsc hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
153 35625b3f 2010-02-23 rsc if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0){
154 35625b3f 2010-02-23 rsc fprint(2,"decrypted file failed to authenticate\n");
155 35625b3f 2010-02-23 rsc exits("decrypted file failed to authenticate");
156 35625b3f 2010-02-23 rsc }
157 35625b3f 2010-02-23 rsc safewrite(copy, ncopy);
158 6e527fbc 2005-02-13 devnull }
159 6e527fbc 2005-02-13 devnull exits("");
160 6e527fbc 2005-02-13 devnull return 1; /* gcc */
161 6e527fbc 2005-02-13 devnull }