What exactly is a subkey?
This post by user rjh from 2008 in the enigmail forum answers it well:
Originally in PGP 2.6, back in the early 90s, you had just one keypair and it was used for both encryption and signing. The ability to have additional keypairs presented some engineering challenges. Ultimately, it was decided that the additonal keypairs would be called "subkeys", despite the fact there's nothing "sub" about them. Likewise, what you call your "key" isn't really a key at all--the terminology is a holdover from the days when a key really was a key. Nowadays, a key is really a collection of keys, along with some metadata for user identifiers, signatures, etc.
E.g., my "key" has four keypairs on it: 5B8709EB, D0C6AAE4, 71E177DB and 8DB02BBB3.
What GnuPG calls your "public key" is really the oldest signing key in the collection. E.g., since 5B8709EB was created first, GnuPG calls the entire set of keys and metadata the "5B8709EB key".
So, "is it possible to have a key that's used for encryption and signing without any subkey at all?" The answer here is no, because all keypairs on a key are subkeys. Even if there's only one of them.
Subkeys
Subkey packets are defined in RFC 4880, OpenPGP, 5.5 Key Material Packet. They're only distinguished by another packet ID, and require a binding signature to be actually useful (see below).
A Public-Subkey packet (tag 14) has exactly the same format as a Public-Key packet, but denotes a subkey.
Subkey Usage
OpenPGP subkeys are used for different purposes:
- Being able to store the primary key offline or a more secure device. If a machine with a subkey is harmed, you can easily revoke the subkey without all the hassles of revoking your primary key (sharing a new key, getting new signatures, ...).
- Having different subkeys on different machines, for example a signing subkey on a build server. Again, revoking single keys is easy.
- Using a larger primary key for long lifetime, and shorter, but faster subkeys for day-to-day usage.
- Some algorithms do not support both encrypting and signing. For example, a DSA primary key requires another key for encryption, typically paired with ElGamal.
Binding Signatures
There are special signature subtypes to bind subkeys to primary keys (and vice verse), listed in RFC 4880, OpenPGP, 5.2.1 Signature Types:
0x18: Subkey Binding Signature
This signature is a statement by the top-level signing key that indicates that it owns the subkey. This signature is calculated directly on the primary key and subkey, and not on any User ID or other packets. A signature that binds a signing subkey MUST have an Embedded Signature subpacket in this binding signature that contains a 0x19 signature made by the signing subkey on the primary key and subkey.
0x19: Primary Key Binding Signature
This signature is a statement by a signing subkey, indicating that it is owned by the primary key and subkey. This signature is calculated the same way as a 0x18 signature: directly on the primary key and subkey, and not on any User ID or other packets.