summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cryptsetup/cryptsetup.c
diff options
context:
space:
mode:
authortaruti <taruti@violetti.org>2011-05-24 22:19:33 +0000
committertaruti <taruti@violetti.org>2011-05-24 22:19:33 +0000
commit9655db255097b84cf742b7a33c74432d4eb3425a (patch)
tree81dd1509453d330ac9e94ca6f5b1a7fe7bdbba2d /sys/src/cmd/cryptsetup/cryptsetup.c
parentf34231e16a9780a1aa1b9fe5dad1776dd82caa44 (diff)
devfs crypto code - alpha version
Diffstat (limited to 'sys/src/cmd/cryptsetup/cryptsetup.c')
-rw-r--r--sys/src/cmd/cryptsetup/cryptsetup.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/sys/src/cmd/cryptsetup/cryptsetup.c b/sys/src/cmd/cryptsetup/cryptsetup.c
new file mode 100644
index 000000000..f3b0b43ee
--- /dev/null
+++ b/sys/src/cmd/cryptsetup/cryptsetup.c
@@ -0,0 +1,173 @@
+// Author Taru Karttunen <taruti@taruti.net>
+// This file can be used as both Public Domain or Creative Commons CC0.
+#include <u.h>
+#include <libc.h>
+#include "crypt.h"
+
+void format(char *file);
+void copen(char *file);
+char*readcons(char *prompt, char *def, int raw, char *buf, int nbuf);
+int pkcs5_pbkdf2(const unsigned char *pass, int pass_len, const unsigned char *salt, int salt_len, unsigned char *key, int key_len, int rounds);
+
+void
+usage(void)
+{
+ print("usage: \ncryptsetup -f deviceorfile \t\t\t\t\t# Format file or device\ncryptsetup -o deviceorfile >> /dev/fs/ctl \t# Open file or device\n");
+ exits("usage");
+}
+
+enum
+{
+ NoMode,
+ Format,
+ Open,
+};
+
+
+void
+main(int argc, char *argv[])
+{
+ int mode;
+ char *file;
+
+ mode = 0;
+
+ ARGBEGIN {
+ default:
+ usage();
+ case 'f':
+ mode = Format;
+ break;
+ case 'o':
+ mode = Open;
+ break;
+ } ARGEND;
+
+ if((mode == NoMode) || (argc != 1))
+ usage();
+
+ file = argv[0];
+
+ switch(mode) {
+ case Format:
+ format(file);
+ break;
+ case Open:
+ copen(file);
+ break;
+ }
+}
+
+void
+format(char *file)
+{
+ char trand[48], pass1[64], pass2[64];
+ unsigned char tkey[16], tivec[16], buf[64*1024];
+ XtsState s;
+ AESstate cbc;
+ int i,j, fd;
+
+ do {
+ readcons("password", nil, 1, pass1, 64);
+ readcons("confirm", nil, 1, pass2, 64);
+ } while(strcmp(pass1, pass2) != 0);
+
+ do {
+ readcons("Are you sure you want to delete all data? (YES to procees)", nil, 0, (char*)buf, 4);
+ } while(strcmp((char*)buf, "YES") != 0);
+
+ srand(truerand());
+
+ for(i = 0; i < 16*4096; i++)
+ buf[i] = rand();
+
+ for(i = 0; i < 48; i+=4)
+ *((unsigned*)&trand[i]) = truerand();
+ memcpy(s.Master, trand, 32);
+ memcpy(s.Slots[0].Salt, trand+32, 16);
+
+ pkcs5_pbkdf2((unsigned char*)pass1, strlen(pass1), s.Slots[0].Salt, 16, (unsigned char*)tkey, 16, 9999);
+ memset(tivec, 0, 16);
+ setupAESstate(&cbc, tkey, 16, tivec);
+ memcpy(s.Slots[0].Key, s.Master, 32);
+ aesCBCencrypt(s.Slots[0].Key, 32, &cbc);
+
+ for(i=0; i<16; i++)
+ for(j=0; j<8; j++) {
+ buf[(4096*i)] = 1;
+ buf[(4096*i)+(4*j)+1] = s.Slots[j].Salt[i];
+ buf[(4096*i)+(4*j)+2] = s.Slots[j].Key[i];
+ buf[(4096*i)+(4*j)+3] = s.Slots[j].Key[i+16];
+ }
+
+ if((fd = open(file, OWRITE)) < 0)
+ exits("Cannot open disk");
+
+ /* make the pad for checking crypto */
+ for(i=0; i<8; i++) {
+ buf[(64*1024)-8+i] = ~buf[(64*1024)-16+i];
+ }
+ memset(tivec, 0, 16);
+ setupAESstate(&cbc, s.Master, 16, tivec);
+ aes_encrypt(cbc.ekey, cbc.rounds, &buf[(64*1024)-16], &buf[(64*1024)-16]);
+
+ write(fd, buf, 16*4096);
+
+ print("Disk written\n");
+}
+
+void copen(char *file) {
+ unsigned char pass[32], buf[1024*64], tkey[16], tivec[16];
+ XtsState s;
+ int i,j,fd;
+ AESstate cbc;
+ char *base, fdpath[1024];
+
+
+ if((fd = open(file, OREAD)) < 0)
+ exits("Cannot open disk");
+
+ if(read(fd, buf, 1024*64) != 1024*64)
+ exits("Cannot read disk");
+
+ for(i=0; i<16; i++)
+ for(j=0; j<8; j++) {
+ s.Slots[j].Salt[i] = buf[(4096*i)+(4*j)+1];
+ s.Slots[j].Key[i] = buf[(4096*i)+(4*j)+2];
+ s.Slots[j].Key[i+16] = buf[(4096*i)+(4*j)+3];
+ }
+
+
+
+ openpass:
+ readcons("Password", nil, 1, (char*)pass, 32);
+
+ memcpy(s.Master, s.Slots[0].Key, 32);
+
+ pkcs5_pbkdf2(pass, strlen((char*)pass), s.Slots[0].Salt, 16, tkey, 16, 9999);
+ memset(tivec, 0, 16);
+ setupAESstate(&cbc, tkey, 16, tivec);
+ aesCBCdecrypt(s.Master, 32, &cbc);
+
+ memset(tivec, 0, 16);
+ setupAESstate(&cbc, s.Master, 16, tivec);
+
+ aes_decrypt(cbc.dkey, cbc.rounds, &buf[(64*1024)-16], &buf[(64*1024)-16]);
+
+ /* make the pad for checking crypto */
+ for(i=0; i<8; i++)
+ if((buf[(64*1024)-8+i] ^ buf[(64*1024)-16+i]) != 255) {
+ goto openpass;
+ }
+
+ base = utfrrune(file, '/');
+ fd2path(fd, fdpath, 1024);
+ j = sprint((char*)buf, "crypt %s %s ", base ? base+1 : file, fdpath);
+
+ for(i=0; i<32; i++) {
+ sprint((char*)&buf[j], "%02X", s.Master[i]);
+ j += 2;
+ }
+ sprint((char*)&buf[j], "\n");
+ print("%s\n", (char*)buf);
+} \ No newline at end of file