dmitrystu / sboot_stm32

Secure USB DFU1.1 bootloader for STM32
Apache License 2.0
303 stars 63 forks source link

Need a checksum only feature in fwcrypt #49

Closed salyzyn closed 2 years ago

salyzyn commented 2 years ago

If one flashes an sboot_stm32 bootblock, which can only be performed with a programmer connected to the SWD interfaces, and then continued to flash the 'application' through the same SWD interfaces, then the device will not boot because there is no trailing checksum in the 'application' when flashed raw like that.

One could switch, then dfu-flash the application signed and encrypted of course, the workaround. But for expediency it would have been 'nice' if fwcrypt could also make a checksummed, but not encrypted, image that could be flashed via SWD.

Suggest adding a -C (uppercase) to suppress enCryption ala the following so that the tool can be leveraged to construct the configured checksum'd raw binary image:

diff --git a/src/encrypter.c b/src/encrypter.c
index 9d67e98..561bba4 100644
--- a/src/encrypter.c
+++ b/src/encrypter.c
@@ -39,6 +39,7 @@ static void exithelp(void) {
            "\t -d Decrypt\n"
            "\t -n No output (dry run)\n"
            "\t -c Without checksum signature\n"
+           "\t -C Without encryption/decryption\n"
            "\t -v VID:PID append DFU suffix (encrypt only)\n"
     );
     exit(0);
@@ -128,6 +129,7 @@ int main(int argc, char **argv)
 {
     int dir = 1;
     int crc = 1;
+    int crypt = 1;
     int dry = 0;
     char *infile = NULL;
     char *outfile = NULL;
@@ -136,7 +138,7 @@ int main(int argc, char **argv)

     opterr = 0;

-    while ((c = getopt(argc, argv, "edchni:o:v:")) != -1)
+    while ((c = getopt(argc, argv, "edcChni:o:v:")) != -1)
         switch (c)
         {
         case 'e':
@@ -148,6 +150,9 @@ int main(int argc, char **argv)
         case 'c':
             crc = 0;
             break;
+   case 'C':
+       crypt = 0;
+       break;
         case 'n':
             dry = 1;
             break;
@@ -228,11 +233,13 @@ int main(int argc, char **argv)
 #endif

 #if(DFU_CIPHER != _DISABLE)
-        if (length % aes_blksize) {
-            length += (aes_blksize - (length % aes_blksize));
+   if (crypt) {
+            if (length % aes_blksize) {
+                length += (aes_blksize - (length % aes_blksize));
+            }
+            printf("Encrypting %zd bytes using %s cipher.\n", length, aes_name);
+            aes_encrypt(buf, buf, length);
         }
-        printf("Encrypting %zd bytes using %s cipher.\n", length, aes_name);
-        aes_encrypt(buf, buf, length);
 #endif

         if (vidpid != 0) {
@@ -253,8 +260,10 @@ int main(int argc, char **argv)
     } else {

 #if(DFU_CIPHER != _DISABLE)
-        printf("Decrypting %zd bytes using %s cipher.\n", length, aes_name);
-        aes_decrypt(buf, buf, length);
+   if (crypt) {
+            printf("Decrypting %zd bytes using %s cipher.\n", length, aes_name);
+            aes_decrypt(buf, buf, length);
+   }
 #endif

 #if (DFU_VERIFY_CHECKSUM != _DISABLE)
salyzyn commented 2 years ago

NB: workaround: hardcode and make a no-encryption configuration and build a separately managed copy of fwcrypt that follows that configuration.

dmitrystu commented 2 years ago

Will be implemented soon. PR is welcome.