View Source OpenPGP.S2KSpecifier (OpenPGP v0.6.2)
Represents structured data for String-to-Key specifier.
RFC4880
3.7. String-to-Key (S2K) Specifiers
String-to-key (S2K) specifiers are used to convert passphrase strings into symmetric-key encryption/decryption keys. They are used in two places, currently: to encrypt the secret part of private keys in the private keyring, and to convert passphrases to encryption keys for symmetrically encrypted messages.
3.7.1. String-to-Key (S2K) Specifier Types
There are three types of S2K specifiers currently supported, and some reserved values:
ID S2K Type
-- --------
0 Simple S2K
1 Salted S2K
2 Reserved value
3 Iterated and Salted S2K
100 to 110 Private/Experimental S2K
These are described in Sections 3.7.1.1 - 3.7.1.3.
3.7.1.1. Simple S2K
This directly hashes the string to produce the key data. See below for how this hashing is done.
Octet 0: 0x00
Octet 1: hash algorithm
Simple S2K hashes the passphrase to produce the session key. The manner in which this is done depends on the size of the session key (which will depend on the cipher used) and the size of the hash algorithm's output. If the hash size is greater than the session key size, the high-order (leftmost) octets of the hash are used as the key.
If the hash size is less than the key size, multiple instances of the hash context are created -- enough to produce the required key data. These instances are preloaded with 0, 1, 2, ... octets of zeros (that is to say, the first instance has no preloading, the second gets preloaded with 1 octet of zero, the third is preloaded with two octets of zeros, and so forth).
As the data is hashed, it is given independently to each hash context. Since the contexts have been initialized differently, they will each produce different hash output. Once the passphrase is hashed, the output data from the multiple hashes is concatenated, first hash leftmost, to produce the key data, with any excess octets on the right discarded.
3.7.1.2. Salted S2K
This includes a "salt" value in the S2K specifier -- some arbitrary data -- that gets hashed along with the passphrase string, to help prevent dictionary attacks.
Octet 0: 0x01
Octet 1: hash algorithm
Octets 2-9: 8-octet salt value
Salted S2K is exactly like Simple S2K, except that the input to the hash function(s) consists of the 8 octets of salt from the S2K specifier, followed by the passphrase.
3.7.1.3. Iterated and Salted S2K
This includes both a salt and an octet count. The salt is combined with the passphrase and the resulting value is hashed repeatedly. This further increases the amount of work an attacker must do to try dictionary attacks.
Octet 0: 0x03
Octet 1: hash algorithm
Octets 2-9: 8-octet salt value
Octet 10: count, a one-octet, coded value
The count is coded into a one-octet number using the following formula:
#define EXPBIAS 6
count = ((Int32)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
The above formula is in C, where "Int32" is a type for a 32-bit integer, and the variable "c" is the coded count, Octet 10.
Iterated-Salted S2K hashes the passphrase and salt data multiple times. The total number of octets to be hashed is specified in the encoded count in the S2K specifier. Note that the resulting count value is an octet count of how many octets will be hashed, not an iteration count.
Initially, one or more hash contexts are set up as with the other S2K algorithms, depending on how many octets of key data are needed. Then the salt, followed by the passphrase data, is repeatedly hashed until the number of octets specified by the octet count has been hashed. The one exception is that if the octet count is less than the size of the salt plus passphrase, the full salt plus passphrase will be hashed even though that is greater than the octet count. After the hashing is done, the data is unloaded from the hash context(s) as with the other S2K algorithms.
Summary
Functions
Decode String-to-Key specifier given input binary. Return structured specifier and remaining binary.
Types
Functions
@spec build_session_key(t(), key_size :: pos_integer(), passphrase :: binary()) :: binary()
Decode String-to-Key specifier given input binary. Return structured specifier and remaining binary.