Rooting the KORG Kronos

Disclaimer: The following file is provided without any warranties. Backup all your settings before using it - maybe you'll need to ...


Dienstag, 31. Mai 2016

Kronos encrypted file systems

Korg uses Cryptoloop to hide the important parts of it's Kronos firmware from prying eyes. The mount mechanism is somewhat obfuscated and hidden in loadmod.ko and loadoa. Here is a brief description:
  1. loadoa loads the kernel module loadmod.ko
  2. loadmod.ko replaces the kernel's mount syscall with it's own implementation (but only if filesystem check, kernel check and communication with the security chip are ok).
  3. loadmod.ko reads and decrypts /.pairFact3 to retrieve the Cryptoloop keys. The Cryptoloop keys are the same for all devices, but the keys to decrypt /.pairFact3 are individual for each device. When you "authorize" your Kronos, you actually get the Cryptoloop keys encrypted with your individual device keys.
  4. loadoa mounts issues a mount command that looks like this:
    /bin/mount -n -t ignoreType ignoreDev /korg/rw/PCM/WaveMotion
  5. loadmod.ko gets the syscall and recognizes the "magic" mount point name (/korg/rw/PCM/WaveMotion). Now it initializes the Cryptoloop device and calls the kernel's normal mount syscall handler to mount the loop device.
Now, it would be nice to have the Cryptoloop keys for the encrypted file systems inside the Kronos firmware. You can easily extract the encrypted files from the Kronos firmware updates published by Korg. If we just had the keys, we could mount and examine them on any PC around.

The possibility to boot our own kernel helps a lot, here. One could just add some printk() to a function that handles the cryptoloop keys (for example loop_set_status).

This is the kernel patch. Let's see what happens...

loop_set_status(0): lo_file_name=/korg/ro/Eva.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=342ee59d549c7d329d835537be0540d
loop_set_status(1): lo_file_name=/korg/ro/WaveMotion.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=3e72c0e59fc017a9eb7d7e1168a4cdb
loop_set_status(2): lo_file_name=/korg/ro/Mod.img lo_encrypt_type=18 lo_crypt_name=aes lo_encrypt_key=a336a15cd841ec8926b99e7c3884eaa

Crazy keys

Looking at struct loop_info64 it is pretty clear that the simple printk("... lo_encrypt_key=%s ...", status->lo_encrypt_key) should not have worked. lo_encrypt_key should be binary, not a null terminated string!

Someone had no real clue about how to use loop_set_status() and used 31 (plus a \0 byte for string termination) hex digits (containing only 124 bits of information) as AES256 key.

I am still wondering if this is just a stupid mistake or just one more strange obfuscation. 

Montag, 23. Mai 2016

A short look into the past: OASYS

The Kronos' history actually began more than ten years ago with the OASYS. Back then, when the OASYS was released, I really wanted to have one, but I also really could not afford it. So I decided to hack other stuff and kind of forgot about the OASYS.

Now, ten years later, I got the chance to look into the architecture and the software of the OASYS and the similarities to the Kronos are astonishing. The architecture is almost the same and I would be tempted to say that the Kronos is in fact a "OASYS Lite V2".

Why "Lite"? Because the Kronos misses many expensive parts (LEDs around knobs/sliders, trigger buttons, large screen, CD drive, ...). It looks like the goal set for the Kronos product engineering was to build a more affordable version of the OASYS (which makes perfect sence, if you look at the price tag of the OASYS).

Why "V2"? Because the Kronos has some features (more engines, sample streaming) that the OASYS lacks. I am wondering why Korg did not upgrade the OASYS software to include those features. Maybe hardware limitations were the reason. The OASYS has no SSD, so disk access latency might be the reason there is no sample streaming. Also, the OASYS has a single core CPU (Pentium 4) while the Kronos has a dual core (Atom). It would be interesting to benchmark the single core P4 against the dual core Atom... (Update: Comparison between OASYS and Kronos CPUs. Looks like the P4 is faster in single core workloads, but the Atom is faster in multi core workloads. A synthesizer is almost a perfect multi core workload, so the Kronos is in fact more powerful than the OASYS).

However, the software and hardware architecture between OASYS and Kronos are so similar that most articles in this blog are - to a certain degree - also valid for the OASYS.

Here are - in no particular order - some things I noticed while comparing OASYS and Kronos:

  • Both use Linux with RTAI realtime extensions. However, OASYS uses Linux 2.4, Kronos uses Linux 2.6
  • Security stuff (filesystem integrity check, security ic, authorization file) is almost identical
  • The OASYS uses the VGA output of the mainboard for it's display while the Kronos uses a display connected to the OMAP. This means that the Kronos has to transfer all display data over USB. I am unsure why they did this - the Kronos mainboard also has a VGA connector, but it is unused.
  • In the OASYS the whole control surface (including the keybed) is connected via USB. On the Kronos, the keybed is connected to the mainboard via RS232 - the rest of the controls are still connected via USB. Maybe latency reduction?
  • The OASYS uses a custom PCI sound card while the Kronos uses a custom USB sound card for Audio/Midi I/O
Looking at all this, I am wondering why Korg sticks to meaningless upgrades like different colors or different end-plates for it's new/special editions. How about a bigger screen, LEDs for knobs and sliders and some pressure sensitive drum pads? Add a decent mainboard for increased polyphony and call it "platinum edition". KORG, are you listening???

Donnerstag, 5. Mai 2016

Streamlining the Kronos boot process / what does loadmod.ko do?

I have already sched some light on the Kronos boot process in an older article (What does /sbin/loadoa do?). There you can see that a kernel module called "loadmod.ko" is loaded just before the encrypted loop files are mounted.

loadmod.ko plays a vital role in booting the Kronos and is the center of Korg's attempts to protect the Kronos from hacking.

So, what does loadmod.ko do?

  1. First, loadmod.ko performs a file system integrity check. It opens and reads a lot of files and hashes them using MD5. The hash is then compared to a constant value encoded in loadmod.ko. If the values do not match, loadmod.ko will bail out with error code 1.
  2. Next, the Linux kernel is checked. loadmod.ko calls the functions register_cdrom() and init_cdrom_command() with some magic values. A normal Linux kernel will just return error codes because the parameters make no sense. The Linux kernel delivered by Korg has modified versions of this functions that return other magic values to signal loadmod.ko that the kernel is "genuine".

    Korg has not published the source code for those modifications to the Linux kernel even though they are distributing a binary version of Linux with those modifications. This is a clear violation of the GPL.

    You can find a more detailed description of the kernel authentication mechanism in About the Linux kernel used in KORG Kronos.

    I provide a patch that reimplements the modified register_cdrom()/init_cdrom_command() functions here. With this patch you can compile your own kernel that will be accepted by loadmod.ko.

    If the kernel check fails, loadmod.ko will bail out with error code 3.
  3. After filesystem and kernel have been checked, loadmod.ko tries to read the authorization file called "pairFact". This file contains the encryption keys for the encrypted file systems in the Kronos (detailed explanation). If loadmod.ko cannot read that authorization data, it will bail
    out with error code 4.
  4. The contents of "pairFact" are encrypted with a key stored in the security IC. So, the next step for loadmod.ko is to talk to the security IC (the primitives for the communication are provided by OmapNKS4Module.ko. The Public ID of the Kronos is read and the key needed to decrypt the authorization data is read. If communication with the security IC fails, loadmod.ko will bail out with error code 5.
  5. If all checks were successful, a magic value (0x22FB39CC) is stored at a certain address in kernel memory. This magic value will be checked by the synthesizer module (OA.ko) later. If it is not there, OA.ko will skip some important initializations which will cause the sound output to be bad. So even if you do not need loadmod.ko anymore because you have copied the synthesizer files out of the encrypted file systems, you still need to run loadmod.ko (or at least write this magic value) to have useful sound output.
  6. The error code (or zero if there were no errors) from the checks above is written to "/tmp/stgStatus". This is used by /sbin/loadoa to display a more or less useful error message (or the reauthentication screen) if one of the integrity checks failed.
  7. Now, things are getting crazy: loadmod.ko replaces some of the kernel's syscalls by overwriting sys_call_table. The following syscalls are overwritten: sys_mount, sys_ioctl, sys_oldumount, sys_umount, sys_create_module, sys_init_module.

    The syscalls sys_mount and sys_oldumount are replaced with versions that "magically" mount a cryptoloop filesystem if one of the magic paths (/korg/Eva, /korg/Mod, /korg/WaveMotion) is mounted.

    The other syscall replacements don't do anything but call the original handlers. It looks like Korg wanted to prevent users from loading additional modules (maybe to prevent access to the kernel memory), but that mechanism was not finished.
  8. Finally, a kernel thread is started. This kernel thread will handle system updates by listening on /proc/.update and running /sbin/UpdateOS or /tmp/UpdateOS as a usermode helper if necessary.

So, why is that interesting?

From a users point of view, loadmod.ko doesn't do many useful things. The filesystem integrity checks take precious boot time and prevent you from changing your file system. The encrypted loop file systems also degrade system performance and you can easily copy their contents onto the unencrypted file system, 

However, if you decide to save boot time and trouble by getting rid of loadmod.ko, you still have to write the magic value or else the Kronos' sound will be crippled.

I have updated my kernel patches and my precompiled kernel to do that, Using this kernel, you do not need to load loadmod.ko. You can get rid of the filesystem/kernel integrity check and still OA.ko will work perfectly.