5. HMAC and the Pseudorandom Function (HMAC e la funzione pseudocasuale)
Il livello di record TLS utilizza un codice di autenticazione messaggi con chiave (MAC, Message Authentication Code) per proteggere l'integrità dei messaggi. Le suite di cifratura definite in questo documento utilizzano una costruzione nota come HMAC, descritta in [HMAC], che si basa su una funzione hash. Altre suite di cifratura POSSONO definire le proprie costruzioni MAC, se necessario.
Inoltre, è necessaria una costruzione per espandere i segreti in blocchi di dati per scopi di generazione o validazione delle chiavi. Questa funzione pseudocasuale (PRF, pseudorandom function) prende come input un segreto, un seed e un'etichetta identificativa e produce un output di lunghezza arbitraria.
In questa sezione, definiamo una PRF, basata su HMAC. Questa PRF con la funzione hash SHA-256 viene utilizzata per tutte le suite di cifratura definite in questo documento e nei documenti TLS pubblicati prima di questo documento quando viene negoziato TLS 1.2. Le nuove suite di cifratura DEVONO specificare esplicitamente una PRF e, in generale, DOVREBBERO utilizzare la PRF TLS con SHA-256 o una funzione hash standard più forte.
Innanzitutto, definiamo una funzione di espansione dati, P_hash(secret, data), che utilizza una singola funzione hash per espandere un segreto e un seed in una quantità arbitraria di output:
P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
HMAC_hash(secret, A(2) + seed) +
HMAC_hash(secret, A(3) + seed) + ...
dove + indica la concatenazione.
A() è definito come:
A(0) = seed
A(i) = HMAC_hash(secret, A(i-1))
P_hash può essere iterato tante volte quante necessario per produrre la quantità richiesta di dati. Ad esempio, se P_SHA256 viene utilizzato per creare 80 byte di dati, dovrà essere iterato tre volte (fino ad A(3)), creando 96 byte di dati di output; gli ultimi 16 byte dell'iterazione finale verranno quindi scartati, lasciando 80 byte di dati di output.
La PRF di TLS viene creata applicando P_hash al segreto come segue:
PRF(secret, label, seed) = P_<hash>(secret, label + seed)
L'etichetta (label) è una stringa ASCII. Dovrebbe essere inclusa nella forma esatta in cui è data senza byte di lunghezza o carattere null finale. Ad esempio, l'etichetta "slithy toves" verrebbe elaborata eseguendo l'hash dei seguenti byte:
73 6C 69 74 68 79 20 74 6F 76 65 73