summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Makefile13
-rw-r--r--README.md65
-rw-r--r--decrypt.c57
-rw-r--r--deonebook.c64
-rw-r--r--deonebook.h3
-rw-r--r--extract.sh2
-rw-r--r--getkey.c46
m---------tiny-AES-c0
9 files changed, 177 insertions, 76 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d64d040
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "tiny-AES-c"]
+ path = tiny-AES-c
+ url = https://github.com/kokke/tiny-AES-c
diff --git a/Makefile b/Makefile
index c0739f1..80ece1b 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
CC=c99
LD=$(CC)
-CFLAGS=-Wall -Wextra -Wpedantic -Werror -g
+CFLAGS=-Wall -Wextra -Wpedantic -Werror -g3
LDFLAGS=
LDLIBS=
SRCDIR=.
@@ -32,5 +32,16 @@ $(OBJDIR)/genkey.o: $(SRCDIR)/deonebook.h
$(OBJDIR)/genkey.o: $(SRCDIR)/genkey.c
$(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/genkey.c
+$(BINDIR)/deonebook: $(OBJDIR)/decrypt.o
+$(OBJDIR)/decrypt.o: $(SRCDIR)/deonebook.h
+$(OBJDIR)/decrypt.o: $(SRCDIR)/decrypt.c
+$(OBJDIR)/decrypt.o: $(SRCDIR)/tiny-AES-c/aes.c
+ $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/decrypt.c
+
+$(BINDIR)/deonebook: $(OBJDIR)/getkey.o
+$(OBJDIR)/getkey.o: $(SRCDIR)/deonebook.h
+$(OBJDIR)/getkey.o: $(SRCDIR)/getkey.c
+ $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/getkey.c
+
$(BINDIR)/deonebook:
$(LD) $(LDFLAGS) -o $@ $(OBJDIR)/*.o $(LDLIBS)
diff --git a/README.md b/README.md
index f2ca53d..7d5509c 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
DeOneBook
---------
-This program extracts encryption keys from eOneBook SD cards. Eventually I will
-add decryption as well, but for now it is enough to extract a key that can be
-used passed to `openssl` to do the actual decryption.
+This program is designed to decrypt the contents of eOneBook SD cards. It is
+able to extract the encryption keys from SD cards to make this automatic with
+the proper hardware. Without hardware support, decryption is a two-step
+process, extracting a key using the eOneBook itself, and decryption using that
+key.
Building
--------
@@ -25,22 +27,29 @@ Then build with the cross compiler:
make CC=arm-linux-gnueabihf-gcc
-Use
----
+Automatic Decryption
+--------------------
-If you are using the native version, simply place an eOneBook SD card in your
-SD card reader, and run:
+If your system has a directly connected SD card reader, you can decrypt files
+with:
- ./deonebook -G [devicename]
+ deonebook [-d devicename] <input-file> <output-file>
-Here, `devicename` is optional, and will default to `mmcblk0`. If your SD card
-has a different device name, specify it there. The encryption key will be
-presented in hexadecimal.
+The default device is `mmcblk0`. If your SD card reader is something else
+(n.b. it *must* be an `mmcblk` device), specify that via the `-d` option.
+Replace <input-file> with the path to an encrypted file (e.g.
+`/media/sd/001/100E`) and <output-file> with the path to place the newly
+decrypted file. DeOneBook will determine the encryption key by reading
+information directly from the SD card.
-For the eOneBook version, it's a little more complex. You'll need to prep the
-SD card to execute the program and save its output. First, make sure the SD
-card is not write-protected by moving the write-protect slider to the end of
-its slot nearest the pins of the card. Mount the SD card somewhere you can
+On-device Key Extraction
+------------------------
+
+If your system does not have a directly connected SD card reader, you can
+use your eOneBook device to extract the encryption key. You'll need to prep
+the SD card to execute the program and save its output. First, make sure the
+SD card is not write-protected by moving the write-protect slider to the end
+of its slot nearest the pins of the card. Mount the SD card somewhere you can
write to it, `cd` to that mount point, and run the following commands,
replacing `$DEONEBOOKDIR` with the path to the compiled DeOneBook.
@@ -52,25 +61,21 @@ before attempting this.***
mv .A001 eonebook # rename the official firmware
cp $DEONEBOOKDIR/deonebook . # copy over the key extractor
cp $DEONEBOOKDIR/extract.sh .A001 # copy over the extraction script
+ chmod +x deonebook .A001 # ensure deonebook files are executable
Put the SD card in your eOneBook and open it up. When the official interface
comes up, the key extraction is complete. Close the eOneBook and there will be
-a file called `eonebook.hex` containing the encryption key for that card.
-
-Decrypting
-----------
+a file called `eonebook.key` containing the encryption key for that card.
-Eventually this will be integrated into DeOneBook itself. For now, you can use
-the extracted key along with `openssl` to decrypt files. Replace `$KEY` with
-the hex key, either as printed with the native version or the contents of
-`eonebook.hex` from the cross-compiled version. Replace `$INFILE` with the name
-of an encrypted image (e.g. `002E`), and `$OUTFILE` with a path where you want
-the decrypted image to go:
+Manual Decryption
+-----------------
- openssl aes-128-cbc -d -iv 03030303030303030303030303030303 -K $KEY -in $INFILE -out $OUTFILE
+Once you have extraced the key using your eOneBook, you can use that key to
+manually decrypt that SD card's files. Run:
-You can do a whole directory with something like:
+ deonebook -k $KEY <input-file> <output-file>
- for i in *E; do
- openssl aes-128-cbc -d -iv 03030303030303030303030303030303 -K $KEY -in $i -out $i.gray
- done
+Replace `$KEY` with the contents of `eonebook.key` from the previous step (you
+could also simply replace it with `$(cat eonebook.key)`). Replace <input-file>
+with the path to an encrypted file, and <output-file> with the path for the
+newly decrypted file.
diff --git a/decrypt.c b/decrypt.c
new file mode 100644
index 0000000..b41ed9b
--- /dev/null
+++ b/decrypt.c
@@ -0,0 +1,57 @@
+#define _XOPEN_SOURCE 700
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "deonebook.h"
+
+#define CBC 1
+#define ECB 0
+#define CTR 0
+#include "tiny-AES-c/aes.c"
+
+int decrypt(const unsigned char *key, const char *in, const char *out)
+{
+ int fd = open(in, O_RDONLY);
+ if (fd == -1) {
+ perror(in);
+ return 1;
+ }
+
+ struct stat st;
+ if (fstat(fd, &st) != 0) {
+ perror(in);
+ return 1;
+ }
+
+ unsigned char *buf = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (buf == MAP_FAILED) {
+ perror(in);
+ return 1;
+ }
+
+ close(fd);
+
+ unsigned char iv[IV_SIZE];
+ memset(iv, '\03', sizeof(iv));
+
+ struct AES_ctx ctx = {0};
+ AES_init_ctx_iv(&ctx, key, iv);
+ AES_CBC_decrypt_buffer(&ctx, buf, st.st_size);
+
+ fd = open(out, O_WRONLY | O_CREAT, 0644);
+ if (fd == -1) {
+ perror(out);
+ return 1;
+ }
+
+ write(fd, buf, st.st_size);
+ close(fd);
+
+ return 0;
+}
diff --git a/deonebook.c b/deonebook.c
index f943396..12a67a5 100644
--- a/deonebook.c
+++ b/deonebook.c
@@ -7,21 +7,18 @@
int main(int argc, char *argv[])
{
- enum { DECRYPT, GENERATE, READ } mode = DECRYPT;
+ char *keystring = NULL;
+ char *device = NULL;
int c;
- while ((c = getopt(argc, argv, "RGk:")) != -1) {
+ while ((c = getopt(argc, argv, "k:d:")) != -1) {
switch (c) {
- case 'R':
- mode = READ;
+ case 'k':
+ keystring = optarg;
break;
- case 'G':
- mode = GENERATE;
- break;
-
- case 'k':
- /* keyfile = optarg; */
+ case 'd':
+ device = optarg;
break;
default:
@@ -29,50 +26,29 @@ int main(int argc, char *argv[])
}
}
- if (mode != DECRYPT) {
- unsigned char *key = NULL;
- if (mode == READ) {
- key = readkey("./.shm");
- } else {
- char *device = "mmcblk0";
- if (optind < argc) {
- device = argv[optind];
- }
-
- if (strstr(device, "mmcblk") != device) {
- fprintf(stderr, "device must be an mmcblk device\n");
- return 1;
- }
+ unsigned char *key = getkey(keystring, device);
- char path[256];
- snprintf(path, sizeof(path), "/sys/block/%s/device", device);
- DIR *d = opendir(path);
- if (d == NULL) {
- fprintf(stderr, "device '%s' not found\n", device);
- return 1;
- }
-
- key = genkey(dirfd(d));
- }
-
- if (key == NULL) {
- return 1;
- }
+ if (key == NULL) {
+ return 1;
+ }
+ if (optind >= argc) {
for (int i = 0; i < KEY_SIZE; i++) {
printf("%02hhx", key[i]);
}
printf("\n");
-
return 0;
}
- if (optind >= argc) {
- fprintf(stderr, "%s: missing operands\n", argv[0]);
+ if (optind < argc - 2) {
+ fprintf(stderr, "too many operands\n");
+ return 1;
+ }
+
+ if (optind != argc - 2) {
+ fprintf(stderr, "missing output file\n");
return 1;
}
- do {
- printf("decrypting %s\n", argv[optind]);
- } while (++optind < argc);
+ return decrypt(key, argv[optind], argv[optind + 1]);
}
diff --git a/deonebook.h b/deonebook.h
index 6daf22a..4f77284 100644
--- a/deonebook.h
+++ b/deonebook.h
@@ -2,8 +2,11 @@
#define DEONEBOOK_H
#define KEY_SIZE 16
+#define IV_SIZE 16
unsigned char *genkey(int dirfd);
unsigned char *readkey(const char *path);
+unsigned char *getkey(const char *keystring, const char *device);
+int decrypt(const unsigned char *key, const char *in, const char *out);
#endif
diff --git a/extract.sh b/extract.sh
index 348289e..576e60a 100644
--- a/extract.sh
+++ b/extract.sh
@@ -1,6 +1,6 @@
#!/bin/sh
D=/run/media/mmcblk0p1
-$D/deonebook -R > $D/eonebook.hex
+$D/deonebook > $D/eonebook.key
exec $D/eonebook || shutdown -h now
diff --git a/getkey.c b/getkey.c
new file mode 100644
index 0000000..6e3da12
--- /dev/null
+++ b/getkey.c
@@ -0,0 +1,46 @@
+#define _XOPEN_SOURCE 700
+#include <dirent.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "deonebook.h"
+
+unsigned char *getkey(const char *keystring, const char *device)
+{
+ if (keystring) {
+ static unsigned char key[KEY_SIZE] = "";
+ if (strlen(keystring) != (KEY_SIZE * 2)) {
+ fprintf(stderr, "key must be %d hex characters\n", KEY_SIZE * 2);
+ return NULL;
+ }
+
+ for (size_t i = 0; i < sizeof(key); i++) {
+ char hex[] = { keystring[i * 2], keystring[i * 2 + 1], '\0' };
+ key[i] = (unsigned char)strtoul(hex, NULL, 16);
+ }
+ return key;
+ }
+
+ if (!device) {
+ device = "mmcblk0";
+ } else if (strstr(device, "mmcblk") != device) {
+ fprintf(stderr, "device must be an mmcblk device\n");
+ return NULL;
+ }
+
+ char path[256];
+ snprintf(path, sizeof(path), "/sys/block/%s/device", device);
+ DIR *d = opendir(path);
+ if (d == NULL) {
+ fprintf(stderr, "device '%s' not found\n", device);
+ return NULL;
+ }
+
+ unsigned char *key = genkey(dirfd(d));
+ if (key) {
+ return key;
+ }
+
+ return readkey("./.shm");
+}
diff --git a/tiny-AES-c b/tiny-AES-c
new file mode 160000
+Subproject 3f69a5899e58e2e398e8c32ce7b3a954dd593ed