Recommended

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 ...

Search

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.



Samstag, 2. April 2016

Kronos Polyphony and Performance

As explained in many discussions, the Kronos has no fixed polyphony. The number of sounding voices differs depending on the engine used for each voice and even depending on which effects are currently active.

But how does the sound engine know how many voices can be active? 

The answer is a file called CostProfile in /korg/rw/Startup on your Kronos (this file is not included in the filesystem integrity check, so you can modify this file via FTP/SCP after rooting your Kronos. In this file, the resource cost is stored for each engine and for each effect. The engine uses this file to constantly keep track of the current resource usage. As soon as there are not enough resources for all voices and effects that should be running, some algorithm carefully selects the least audible voices and drops them to make room for new (probably more audible voices).

So, if you upgrade the CPU power of your synthesizer, you still need to patch CostProfile to get increased polyphony. I have prepared a CostProfile for my hardware upgrade here. The proposed setup has enough power to archive 200 note polyphony across all engines and regardless of the active effects,

Patching CostProfile to reduce the resource cost on the original main board (i.e. without additional CPU power) leads to some interesting behavior when too many voices are triggered: instead of stuttering and/or clicking, single voices drop out at random. This is because of a second mechanism called EmergencyVoiceStealer that seems to just drop one or more voices as a last measure to prevent a complete audio dropout. It looks like Korg spent a lot of effort to make sure there are no hard audio dropouts. Wow!

Finally, there is a hard limit of 200 voices. This limit is probably a #define in the synthesizer source code and was set arbitrarily by Korg.

Freitag, 1. April 2016

Precompiled kernel for the Kronos with XHCI support

If you want to roll your own hardware upgrade, and don't want to dive into the details of compiling the Linux kernel, use this precompiled Kronos-compatible kernel with XHCI support.

The kernel was compiled from the ingredients explained here. All patches applied to the Linux kernel 2.6.32.11 to compile the binary linked above are available here.

Update (April 3rd 2016):

  • Enabled IPv6 in kernel config (required for Intel NIC drivers)
  • Fixed problem with selecting OA.ko's heap memory size (orig_mem_size)
  • Driver modules for both Intel NICs on the Supermicro X11SSV-Q (Compiled from e1000e-3.3.3.tar and igb-5.3.4.4.tar.gz).
Driver Modules for Intel NICs on Supermicro X11SSV-Q (extract to /lib/modules/2.6.32.11-korg)

Update (May 5th 2016):

  • Added magic value to register_cdrom() so that OA.ko still works properly if loadmod.ko was not loaded.


Have fun!

Montag, 28. März 2016

Kronos Keybed Communication

While most knobs, buttons and LEDs on the Kronos are connected to the OMAP , the Keybed with the two switches SW1/SW2 and the Pitch Bend Controller "Joystick" are connected to the PC Mainboard.

The communication between Keybed and PC works via the PC's serial port COM1. This serial port is provided by a 16550A compatible UART inside the mainboard's Super-IO chip (Winbond W83627).

The Keybed sends short (1-4 bytes) commands to the PC when keys are pressed or the analog joystick is moved.

There are some oddities:

  • The serial baud rate is 62500 bits/s.
  • The voltage levels between keybed and PC don't match: The PC is using RS232 levels (-10V/+10V) and the keybed is using TTL levels (0V/+5V). It is a strange thing that the connection even works under those circumstances.
  • The synthesizer kernel module (OA.ko) completely bypasses the kernel's serial driver. There is a minimal serial driver embedded in OA.ko
  • The UART baud rate generator is not used with it's default clock of 1.8461 MHz but with an alternative clock of 24 MHz. The baud rate generator clock is switched using the configuration registers of the Super-IO chip. This is also done by OA.ko.
  • OA.ko also reads the ChipID register of the W83627 and refuses to start if this specific Super-IO chip is not present.
Update: The Kronos 2 mainboard (ASRock IMB-140) has a different Super-IO chip: the NCT6627UD. This is a brother of the NCT6776 which is used on my brand new Supermicro X11SSV-Q. The registers required to configure and use the first UART (COM1) are identical on both chips.


Montag, 29. Februar 2016

More power for the Kronos

Let's assume I'd want to replace the Kronos mainboard with something a little more state-of-the-art. Maybe cost is not my main concern (Kronos was expensive enough, a few more spent bucks don't really matter).

Here are some thoughts:

  • Mainboard should be Mini-ITX to fit into the Kronos
  • CPU must support at least the Intel Atom instruction set (Kronos binaries are optimized for Atom)
  • There is no point in having more than 4 GB RAM since OA.ko and the other proprietary kernel modules are 32 Bit only. Update: 8 GB RAM will allow the kernel and userspace applications to live in high memory while OA can use almost all of the low memory. This will squeeze out 200-300 extra MBs of sample memory.
  • There is no point in having more than 2 CPU cores since the signal processing chain is optimized for 2 cores. Each CPU core should be as fast as possible to archive maximum signal processing performance.
  • Hardware needs at least one USB port to connect the NKS4 module (probably not hard).
  • Hardware needs a RS232 port to connect the Keybed, should be 16550 compatible (might be problematic, because most modern mainboards have no serial ports anymore)
Here is what I came up with:
Obstacles to overcome (updated again):
  • Skylake chipsets are XHCI only. XHCI-Driver in Kernel 2.6.32 does not support isochronous transfers. Solved by backporting a newer XHCI-Driver.
  • Memory map is not continuous. There are holes for ACPI NVS. Problematic with KORG's way of allocating the synthesizer's heap in ioremapped memory. Solved by setting TOLUD (Top Of Low Usable DRAM) in BIOS settings to 3.5 GB. ACPI stuff is then out of the way.
  • SuperIO-Driver embedded in OA.ko for serial port doesn't work (no keybed yet). Works with the latest OA.ko versions since SuperIO-Chip in Kronos 2 is similar to the one on the X11SSV-Q. Connection cable inside Kronos needs some soldering since the supermicro board has a SUB-D connector and no pin-header for RS232.
  • Kernel 2.6.32 does not support the ethernet MACs on the SX11SSV-Q. Not a real problem since the mainboard's ethernet connection is unused in the original Kronos design. Backporting a driver from a newer kernel should be possible. Intel provides drivers for both NICs that compile as modules against 2.6.32-11. Get prebuilt modules here.
Results (updated):
  • Kronos boot time < 20s
  • 200 voice polyphony accross all engines (even STR-1 and MS-20). 
  • Total cost: ~ $520