diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2020-06-17 23:31:31 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2020-10-11 13:08:03 +0200 |
commit | 1f338f70789fdb7d6bbd954cc1444f59a156e83c (patch) | |
tree | 272b9bcc571929293053e3cc2680ab27a8fae23a | |
parent | 05fa8fc3435c74090430108001afeafe2d1e9d42 (diff) | |
download | rockbox-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/Makefile | 41 | ||||
-rw-r--r-- | utils/nwztools/upgtools/keysig_search.h | 2 | ||||
-rw-r--r-- | utils/nwztools/upgtools/md5.cpp | 32 | ||||
-rw-r--r-- | utils/nwztools/upgtools/md5.h | 37 | ||||
-rw-r--r-- | utils/nwztools/upgtools/mg.cpp | 191 | ||||
-rw-r--r-- | utils/nwztools/upgtools/mg.h | 5 | ||||
-rw-r--r-- | utils/nwztools/upgtools/misc.c | 14 | ||||
-rw-r--r-- | utils/nwztools/upgtools/upg.c | 3 | ||||
-rw-r--r-- | utils/nwztools/upgtools/upgtool.c | 6 |
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); |