summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2020-06-17 23:31:31 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2020-10-11 13:08:03 +0200
commit1f338f70789fdb7d6bbd954cc1444f59a156e83c (patch)
tree272b9bcc571929293053e3cc2680ab27a8fae23a
parent05fa8fc3435c74090430108001afeafe2d1e9d42 (diff)
downloadrockbox-1f338f7078.tar.gz
rockbox-1f338f7078.zip
nwztools/upgtools: add support for windows
In order to avoid the crypto++ mess, the code uses the Windows Cryptography API, which is standard. There is also some makefile magic to cross-compile: make PREFIX=i686-w64-mingw32- EXE_EXT=.exe I selected the option so that it should statically link supports libraries used by gcc (slsj and libwinpthread). Change-Id: Iaf07da23afe81ed217fb3921ce13367c5441514d
-rw-r--r--utils/nwztools/upgtools/Makefile41
-rw-r--r--utils/nwztools/upgtools/keysig_search.h2
-rw-r--r--utils/nwztools/upgtools/md5.cpp32
-rw-r--r--utils/nwztools/upgtools/md5.h37
-rw-r--r--utils/nwztools/upgtools/mg.cpp191
-rw-r--r--utils/nwztools/upgtools/mg.h5
-rw-r--r--utils/nwztools/upgtools/misc.c14
-rw-r--r--utils/nwztools/upgtools/upg.c3
-rw-r--r--utils/nwztools/upgtools/upgtool.c6
9 files changed, 240 insertions, 91 deletions
diff --git a/utils/nwztools/upgtools/Makefile b/utils/nwztools/upgtools/Makefile
index 5dede1447c..287fe99c65 100644
--- a/utils/nwztools/upgtools/Makefile
+++ b/utils/nwztools/upgtools/Makefile
@@ -1,26 +1,39 @@
DEFINES=
-CC=gcc
-CXX=g++
-LD=g++
-PROFILE=
-PKGCONFIG := $(CROSS)pkg-config
-
+PREFIX?=
+EXE_EXT?=
+CC=$(PREFIX)gcc
+CXX=$(PREFIX)g++
+LD=$(PREFIX)g++
+PKGCONFIG:=$(CROSS)pkg-config
+
+TARGET_TRIPLE:=$(shell $(CC) -dumpmachine)
+ifneq ($(findstring -w64-,$(TARGET_TRIPLE)),)
+ TARGET_OS := Windows
+endif
+
+ifeq ($(TARGET_OS), Windows)
+# -static allows to statically include libwinpthread-1.dll if possible
+CFLAGS+=-gstabs
+CXXFLAGS+=-gstabs
+LDFLAGS+=-static-libgcc -static
+else
# Distros could use different names for the crypto library. We try a list
# of candidate names, only one of them should be the valid one.
LIBCRYPTO_NAMES = libcryptopp libcrypto++ cryptopp crypto++
$(foreach l,$(LIBCRYPTO_NAMES),\
- $(eval LDOPTS += $(shell $(PKGCONFIG) --silence-errors --libs $(l))))
+ $(eval LDLIBS += $(shell $(PKGCONFIG) --silence-errors --libs $(l))))
$(foreach l,$(LIBCRYPTO_NAMES),\
$(eval CFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
$(foreach l,$(LIBCRYPTO_NAMES),\
$(eval CXXFLAGS += $(shell $(PKGCONFIG) --silence-errors --cflags $(l))))
+endif
-CXXFLAGS=-g $(PROFILE) -Wall $(DEFINES)
-CFLAGS=-g $(PROFILE) -Wall -std=c99 $(DEFINES)
-LDFLAGS=$(PROFILE) $(LDOPTS) -lpthread
+CXXFLAGS+=-g -Wall $(DEFINES)
+CFLAGS+=-g -Wall -std=c99 $(DEFINES)
+LDLIBS+=-lpthread
-BINS=upgtool
+BINS=upgtool$(EXE_EXT)
all: $(BINS)
@@ -30,11 +43,11 @@ all: $(BINS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
-upgtool: upgtool.o upg.o misc.o mg.o keysig_search.o md5.o
- $(LD) -o $@ $^ $(LDFLAGS)
+upgtool$(EXE_EXT): upgtool.o upg.o misc.o mg.o keysig_search.o
+ $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
clean:
- rm -fr *.o
+ rm -rf *.o
veryclean:
rm -rf $(BINS)
diff --git a/utils/nwztools/upgtools/keysig_search.h b/utils/nwztools/upgtools/keysig_search.h
index 72649e042e..67461d9b2b 100644
--- a/utils/nwztools/upgtools/keysig_search.h
+++ b/utils/nwztools/upgtools/keysig_search.h
@@ -49,7 +49,7 @@ struct keysig_search_desc_t
const char *comment;
};
-struct keysig_search_desc_t keysig_search_desc[KEYSIG_SEARCH_LAST];
+extern struct keysig_search_desc_t keysig_search_desc[KEYSIG_SEARCH_LAST];
bool keysig_search(int method, uint8_t *enc_buf, size_t buf_sz,
keysig_notify_fn_t notify, void *user, int nr_threads);
diff --git a/utils/nwztools/upgtools/md5.cpp b/utils/nwztools/upgtools/md5.cpp
deleted file mode 100644
index 301eea2d53..0000000000
--- a/utils/nwztools/upgtools/md5.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2012 Amaury Pouly
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "md5.h"
-/* MD5 is considered insecure by crypto++ */
-#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
-#include <cryptopp/cryptlib.h>
-#include <cryptopp/md5.h>
-
-using namespace CryptoPP::Weak;
-
-void MD5_CalculateDigest(void *digest, const void *input, size_t length)
-{
- MD5().CalculateDigest((byte *)digest, (const byte *)input, length);
-}
diff --git a/utils/nwztools/upgtools/md5.h b/utils/nwztools/upgtools/md5.h
deleted file mode 100644
index 1e4b57ab0e..0000000000
--- a/utils/nwztools/upgtools/md5.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2016 Amaury Pouly
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#ifndef __md5_h__
-#define __md5_h__
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Compute the MD5 digest of a buffer */
-void MD5_CalculateDigest(void *digest, const void *input, size_t length);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __md5_h__ */
diff --git a/utils/nwztools/upgtools/mg.cpp b/utils/nwztools/upgtools/mg.cpp
index 4bab5d9c61..df2dbbfd4f 100644
--- a/utils/nwztools/upgtools/mg.cpp
+++ b/utils/nwztools/upgtools/mg.cpp
@@ -19,13 +19,201 @@
*
****************************************************************************/
#include "mg.h"
+
+/* on Windows, we use Cryptography API, on other platforms we rely on crypto++ */
+#if defined(_WIN32) || defined(__WIN32__)
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdio.h>
+
+static HCRYPTPROV g_hCryptProv;
+
+typedef struct
+{
+ BLOBHEADER hdr;
+ DWORD dwKeySize;
+ BYTE rgbKeyData[];
+} PLAINTEXTKEY;
+
+static bool check_context()
+{
+ if(g_hCryptProv)
+ return true;
+ return CryptAcquireContext(&g_hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
+}
+
+static HCRYPTKEY import_key(ALG_ID algid, DWORD mode, const uint8_t *key, int key_size, const uint8_t *iv)
+{
+ if(!check_context())
+ return 0;
+ DWORD blob_size = sizeof(PLAINTEXTKEY) + key_size;
+ PLAINTEXTKEY *key_blob = (PLAINTEXTKEY *)malloc(blob_size);
+ key_blob->hdr.bType = PLAINTEXTKEYBLOB;
+ key_blob->hdr.bVersion = CUR_BLOB_VERSION;
+ key_blob->hdr.reserved = 0;
+ key_blob->hdr.aiKeyAlg = algid;
+ key_blob->dwKeySize = key_size;
+ memcpy(key_blob->rgbKeyData, key, key_size);
+ HCRYPTKEY hKey;
+ if(!CryptImportKey(g_hCryptProv, (const BYTE *)key_blob, blob_size, 0, 0, &hKey))
+ return 0;
+ CryptSetKeyParam(hKey, KP_MODE, (const BYTE *)&mode, 0);
+ if(iv)
+ CryptSetKeyParam(hKey, KP_IV, (const BYTE *)iv, 0);
+ return hKey;
+}
+
+void MD5_CalculateDigest(void *digest, const void *input, size_t length)
+{
+ if(!check_context())
+ return;
+ HCRYPTHASH hHash;
+ if(!CryptCreateHash(g_hCryptProv, CALG_MD5, 0, 0, &hHash))
+ return;
+ if(!CryptHashData(hHash, (const BYTE *)input, length, 0))
+ return;
+ DWORD dwSize = 16;
+ if(!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE *)digest, &dwSize, 0))
+ return;
+ CryptDestroyHash(hHash);
+}
+
+void mg_decrypt_fw(void *in, int size, void *out, uint8_t *key)
+{
+ if(!check_context() || (size % 8) != 0)
+ abort(); /* size must be a multiple of 8 */
+ HCRYPTKEY hKey = import_key(CALG_DES, CRYPT_MODE_ECB, key, 8, NULL);
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptDecrypt(hKey, 0, FALSE, 0, (BYTE *)out, &dwSize);
+ CryptDestroyKey(hKey);
+}
+
+static HCRYPTKEY g_des_ecb_dec_key;
+
+void des_ecb_dec_set_key(const uint8_t key[8])
+{
+ if(g_des_ecb_dec_key)
+ CryptDestroyKey(g_des_ecb_dec_key);
+ g_des_ecb_dec_key = import_key(CALG_DES, CRYPT_MODE_ECB, key, 8, NULL);
+}
+
+void des_ecb_dec(void *in, int size, void *out)
+{
+ if(size % 8)
+ abort(); /* size must be a multiple of 8 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptDecrypt(g_des_ecb_dec_key, 0, FALSE, 0, (BYTE *)out, &dwSize);
+}
+
+static HCRYPTKEY g_des_ecb_enc_key;
+
+void des_ecb_enc_set_key(const uint8_t key[8])
+{
+ if(g_des_ecb_enc_key)
+ CryptDestroyKey(g_des_ecb_enc_key);
+ g_des_ecb_enc_key = import_key(CALG_DES, CRYPT_MODE_ECB, key, 8, NULL);
+}
+
+void des_ecb_enc(void *in, int size, void *out)
+{
+ if(size % 8)
+ abort(); /* size must be a multiple of 8 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptEncrypt(g_des_ecb_enc_key, 0, FALSE, 0, (BYTE *)out, &dwSize, dwSize);
+}
+
+static HCRYPTKEY g_aes_ecb_dec_key;
+
+void aes_ecb_dec_set_key(const uint8_t key[16])
+{
+ if(g_aes_ecb_dec_key)
+ CryptDestroyKey(g_aes_ecb_dec_key);
+ g_aes_ecb_dec_key = import_key(CALG_AES_128, CRYPT_MODE_ECB, key, 16, NULL);
+}
+
+void aes_ecb_dec(void *in, int size, void *out)
+{
+ if(size % 16)
+ abort(); /* size must be a multiple of 16 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptDecrypt(g_aes_ecb_dec_key, 0, FALSE, 0, (BYTE *)out, &dwSize);
+}
+
+static HCRYPTKEY g_aes_ecb_enc_key;
+
+void aes_ecb_enc_set_key(const uint8_t key[16])
+{
+ if(g_aes_ecb_enc_key)
+ CryptDestroyKey(g_aes_ecb_enc_key);
+ g_aes_ecb_enc_key = import_key(CALG_AES_128, CRYPT_MODE_ECB, key, 16, NULL);
+}
+
+void aes_ecb_enc(void *in, int size, void *out)
+{
+ if(size % 16)
+ abort(); /* size must be a multiple of 16 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptEncrypt(g_aes_ecb_enc_key, 0, FALSE, 0, (BYTE *)out, &dwSize, dwSize);
+}
+
+static HCRYPTKEY g_aes_cbc_dec_key;
+
+void aes_cbc_dec_set_key_iv(const uint8_t key[16], const uint8_t iv[16])
+{
+ if(g_aes_cbc_dec_key)
+ CryptDestroyKey(g_aes_cbc_dec_key);
+ g_aes_cbc_dec_key = import_key(CALG_AES_128, CRYPT_MODE_CBC, key, 16, iv);
+}
+
+void aes_cbc_dec(void *in, int size, void *out)
+{
+ if(size % 16)
+ abort(); /* size must be a multiple of 16 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptDecrypt(g_aes_cbc_dec_key, 0, FALSE, 0, (BYTE *)out, &dwSize);
+}
+
+static HCRYPTKEY g_aes_cbc_enc_key;
+
+void aes_cbc_enc_set_key_iv(const uint8_t key[16], const uint8_t iv[16])
+{
+ if(g_aes_cbc_enc_key)
+ CryptDestroyKey(g_aes_cbc_enc_key);
+ g_aes_cbc_enc_key = import_key(CALG_AES_128, CRYPT_MODE_CBC, key, 16, iv);
+}
+
+void aes_cbc_enc(void *in, int size, void *out)
+{
+ if(size % 16)
+ abort(); /* size must be a multiple of 16 */
+ memcpy(out, in, size);
+ DWORD dwSize = size;
+ CryptEncrypt(g_aes_cbc_enc_key, 0, FALSE, 0, (BYTE *)out, &dwSize, dwSize);
+}
+
+
+#else /* Not on Windows */
+/* MD5 is considered insecure by crypto++ */
+#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <cryptopp/cryptlib.h>
#include <cryptopp/modes.h>
#include <cryptopp/des.h>
#include <cryptopp/aes.h>
-#include <stdio.h>
+#include <cryptopp/md5.h>
using namespace CryptoPP;
+using namespace CryptoPP::Weak;
+
+void MD5_CalculateDigest(void *digest, const void *input, size_t length)
+{
+ MD5().CalculateDigest((byte *)digest, (const byte *)input, length);
+}
void mg_decrypt_fw(void *in, int size, void *out, uint8_t *key)
{
@@ -119,3 +307,4 @@ void aes_cbc_enc(void *in, int size, void *out)
abort(); /* size must be a multiple of 16 */
g_aes_cbc_enc.ProcessData((byte*)out, (byte*)in, size);
}
+#endif
diff --git a/utils/nwztools/upgtools/mg.h b/utils/nwztools/upgtools/mg.h
index fe6ec7c2f6..3f7de2cd9b 100644
--- a/utils/nwztools/upgtools/mg.h
+++ b/utils/nwztools/upgtools/mg.h
@@ -22,10 +22,15 @@
#define __mg_h__
#include <stdint.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
+
+/* Compute the MD5 digest of a buffer */
+void MD5_CalculateDigest(void *digest, const void *input, size_t length);
+
/* size must be a multiple of 8, this function is thread-safe */
void mg_decrypt_fw(void *in, int size, void *out, uint8_t key[8]);
diff --git a/utils/nwztools/upgtools/misc.c b/utils/nwztools/upgtools/misc.c
index ed1ba6c788..0fc4542336 100644
--- a/utils/nwztools/upgtools/misc.c
+++ b/utils/nwztools/upgtools/misc.c
@@ -25,6 +25,18 @@
#include <stdarg.h>
#include "misc.h"
+#if defined(_WIN32) || defined(__WIN32__)
+
+const char OFF[] = "";
+
+const char GREY[] = "";
+const char RED[] = "";
+const char GREEN[] = "";
+const char YELLOW[] = "";
+const char BLUE[] = "";
+
+#else
+
const char OFF[] = { 0x1b, 0x5b, 0x31, 0x3b, '0', '0', 0x6d, '\0' };
const char GREY[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '0', 0x6d, '\0' };
@@ -33,6 +45,8 @@ const char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
const char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
const char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
+#endif
+
static bool g_color_enable = true;
void enable_color(bool enable)
diff --git a/utils/nwztools/upgtools/upg.c b/utils/nwztools/upgtools/upg.c
index 910c37a9bf..47b1acb07b 100644
--- a/utils/nwztools/upgtools/upg.c
+++ b/utils/nwztools/upgtools/upg.c
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include "md5.h"
struct nwz_model_t g_model_list[] =
{
@@ -190,7 +189,7 @@ struct upg_file_t *upg_read_memory(void *buf, size_t size, const char *key,
}
else
{
- cprintf(GREY, "I don't know how to decrypt with a key of length %s\n", key_len);
+ cprintf(GREY, "I don't know how to decrypt with a key of length %d\n", key_len);
return NULL;
}
diff --git a/utils/nwztools/upgtools/upgtool.c b/utils/nwztools/upgtools/upgtool.c
index e0ccc15c48..81cb4aa939 100644
--- a/utils/nwztools/upgtools/upgtool.c
+++ b/utils/nwztools/upgtools/upgtool.c
@@ -28,9 +28,7 @@
#include <stdarg.h>
#include <ctype.h>
#include "misc.h"
-#include "elf.h"
#include <sys/stat.h>
-#include "crypt.h"
#include "keysig_search.h"
#include "upg.h"
@@ -197,10 +195,10 @@ static int extract_upg(int argc, char **argv)
}
g_in_file = argv[0];
- FILE *fin = fopen(g_in_file, "r");
+ FILE *fin = fopen(g_in_file, "rb");
if(fin == NULL)
{
- perror("Cannot open boot file");
+ perror("Cannot open UPG file");
return 1;
}
fseek(fin, 0, SEEK_END);