Kaz Wolfe's answer is pretty good, but I want to emphasize and expand on a couple of points....
The last I checked, Shim basically provided a sort of parallel Secure Boot verification feature. It's intended to be used by GRUB, which is designed to launch Linux kernels that are not EFI programs. Thus, Shim registers itself with the EFI in a way that enables follow-on programs to call Shim to verify that binaries are signed. Shim does so in either of two ways:
- Shim's built-in key -- Most Shim binaries, including the one provided as part of Ubuntu, include a built-in Secure Boot key. Ubuntu's Shim includes Canonical's public key, which validates Ubuntu's GRUB and Linux kernel. This key is therefore stored in RAM, and is rather temporary as these things go. The main point of Shim is to enable its follow-on program (GRUB) to perform a Secure Boot type verification -- but GRUB doesn't really do a Secure Boot verification per se, as described shortly. Without Shim, Canonical would need to rely on Microsoft to sign every new release of GRUB and every new Linux kernel, which would be somewhere between impractical and impossible.
- Machine Owner Keys (MOKs) -- MOKs are basically an extension of Shim's built-in key, but they're intended for ordinary users to manipulate. You might use MOKs if you want to launch binaries that aren't signed with Canonical's key. MOKs, like the firmware's built-in Secure Boot keys, are stored in NVRAM; but they're more easily added to NVRAM, via a program called MokManager. Getting MOKs into NVRAM is still tedious enough that most people don't bother, and many people who do have problems with it; but it's easier than taking complete control of your Secure Boot subsystem, as described in my page that you referenced (Managing EFI Boot Loaders for Linux: Controlling Secure Boot).
In most cases, MOKs are not used; if you want to dual-boot Windows and Ubuntu, you'll probably do fine with the firmware's built-in keys and the key embedded in Ubuntu's Shim binary. You'd use MOKs if you want to add another Linux distribution, compile your own kernels, use a boot loader other than GRUB, use third-party kernel modules, etc.
In addition to those two sources, there's also the Secure Boot keys built into the firmware. I don't recall if Shim uses those keys. It would implicitly use them if it uses the EFI's
StartImage() calls (which it does, but I haven't reviewed the context for this answer). My recollection is that its own verification code does not use the firmware's Secure Boot keys when GRUB calls back to see if a kernel is signed, but I might not be remembering that correctly.
As to how Shim integrates into the Secure Boot system, the last I checked, it didn't. IIRC, to launch its follow-on program (GRUB), Shim implements its own binary-loading code, which resembles a stripped-down version of the code in the Tianocore UEFI sample implementation. This code calls Shim's own Secure Boot verification code, which checks a binary against its built-in key and the local MOK list, to launch a binary. (It may also use the firmware's own Secure Boot keys, but I'm not positive of that.) Once GRUB is loaded, it calls Shim's binary-verification function to verify the Linux kernel, which GRUB launches in its own way (not the way the EFI launches EFI programs). Thus, Shim doesn't really integrate itself into the firmware very deeply; it just makes one or two of its functions available to follow-on programs, leaving the
StartImage() EFI functions unchanged.
That said, EFI does provide ways to replace or supplement normal EFI system calls, and some tools do use these methods. For instance, the PreLoader program, which was a tool to do something similar to what Shim does, integrated itself more deeply into the firmware; it used EFI system calls designed to patch broken or obsolete functions to modify
StartImage() so that it would check both the usual UEFI Secure Boot keys and the MOK. PreLoader has pretty well fallen by the wayside; its developers and Shim's developers have cooperated to focus on Shim rather than PreLoader as the standard Linux Secure Boot tool. AFAIK, Shim has not adopted PreLoader's deeper UEFI integration; however, it's been a while since I looked at the code very closely, so I may be out of date on this. That said....
My own rEFInd boot manager uses code that I took from the PreLoader program in order to "glue" Shim's binary verification code into the UEFI's normal verification subsystem. Thus, with rEFInd in the picture, any attempt to launch an EFI program using
StartImage() calls the Shim authentication code first and, if that fails, calls the standard UEFI Secure Boot authentication second. The gummiboot/systemd-boot boot manager does something similar. Both programs do this because they launch the Linux kernel by way of its EFI stub loader, which means that they rely on the EFI
StartImage() calls. This contrasts with GRUB, which is a full boot loader that launches the Linux kernel in its own way, so GRUB doesn't need these EFI system calls to recognize the Shim's key or the local MOK list.
I hope this helps clarify things, but I'm not sure it will. The details of how all this work are pretty messy, and it's been a while since I've dealt with them in any detail, so my own thoughts aren't as organized as they might be.