strongswan/src/libtls/tls_hkdf.h

183 lines
5.4 KiB
C

/*
* Copyright (C) 2020 Pascal Knecht
* Copyright (C) 2020 Méline Sieber
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup tls_hkdf tls_hkdf
* @{ @ingroup libtls
*/
#ifndef TLS_HKDF_H_
#define TLS_HKDF_H_
#include <library.h>
#include <crypto/hashers/hasher.h>
typedef enum tls_hkdf_label_t tls_hkdf_label_t;
typedef struct tls_hkdf_t tls_hkdf_t;
/**
* TLS HKDF labels
*/
enum tls_hkdf_label_t {
TLS_HKDF_EXT_BINDER,
TLS_HKDF_RES_BINDER,
TLS_HKDF_C_E_TRAFFIC,
TLS_HKDF_E_EXP_MASTER,
TLS_HKDF_C_HS_TRAFFIC,
TLS_HKDF_S_HS_TRAFFIC,
TLS_HKDF_C_AP_TRAFFIC,
TLS_HKDF_S_AP_TRAFFIC,
TLS_HKDF_EXP_MASTER,
TLS_HKDF_RES_MASTER,
TLS_HKDF_UPD_C_TRAFFIC,
TLS_HKDF_UPD_S_TRAFFIC,
};
/**
* TLS HKDF helper functions.
*/
struct tls_hkdf_t {
/**
* Set the (EC)DHE shared secret of this connection.
*
* @param shared_secret input key material to use
*/
void (*set_shared_secret)(tls_hkdf_t *this, chunk_t shared_secret);
/**
* Allocate secret of the requested label.
*
* Space for returned secret is allocated and must be freed by the caller.
*
* @param label HKDF label of requested secret
* @param messages handshake messages
* @param secret secret will be written into this chunk, if used
* @return TRUE if secrets derived successfully
*/
bool (*generate_secret)(tls_hkdf_t *this, tls_hkdf_label_t label,
chunk_t messages, chunk_t *secret);
/**
* Allocate traffic encryption key bytes.
*
* Key used to encrypt traffic data as defined in RFC 8446, section 7.3.
* Space for returned secret is allocated and must be freed by the caller.
*
* @param is_server TRUE if server, FALSE if client derives secret
* @param length key length, in bytes
* @param key key will be written into this chunk
* @return TRUE if secrets derived successfully
*/
bool (*derive_key)(tls_hkdf_t *this, bool is_server, size_t length,
chunk_t *key);
/**
* Allocate traffic IV bytes.
*
* IV used to encrypt traffic data as defined in RFC 8446, section 7.3.
* Space for returned secret is allocated and must be freed by the caller.
*
* @param is_server TRUE if server, FALSE if client derives secret
* @param length key length, in bytes
* @param iv IV will be written into this chunk
* @return TRUE if secrets derived successfully
*/
bool (*derive_iv)(tls_hkdf_t *this, bool is_server, size_t length,
chunk_t *iv);
/**
* Allocate finished key bytes.
*
* Key used to compute Finished messages as defined in RFC 8446,
* section 4.4.4. Space for returned secret is allocated and must be freed
* by the caller.
*
* @param server Whether the client or server finish key is derived
* @param finished key will be written into this chunk
* @return TRUE if secrets derived successfully
*/
bool (*derive_finished)(tls_hkdf_t *this, bool server,
chunk_t *finished);
/**
* Export key material.
*
* @param label exporter label
* @param context optional context
* @param messages handshake messages
* @param length key length, in bytes
* @param key exported key material
* @return TRUE if key material successfully exported
*/
bool (*export)(tls_hkdf_t *this, char *label, chunk_t context,
chunk_t messages, size_t length, chunk_t *key);
/**
* Generate resumption PSKs.
*
* @param messages handshake messages
* @param nonce nonce to use for this PSK
* @param psk generated PSK
* @return TRUE if PSK successfully generated
*/
bool (*resume)(tls_hkdf_t *this, chunk_t messages, chunk_t nonce,
chunk_t *psk);
/**
* Generate a PSK binder.
*
* @note The transcript hash is built of the partial ClientHello message up
* to and including the PreSharedKey extension's identities field, excluding
* the actual binders (their length is included in that of the extension(s)
* and message, though), as per RFC 8446, section 4.2.11.2.
*
* @param seed transcript-hash of client_hello to seed the PRF
* @param psk_binder generated psk binder
* @return TRUE if output was generated
*/
bool (*binder)(tls_hkdf_t *this, chunk_t seed, chunk_t *psk_binder);
/**
* Use the internal PRF to allocate data (mainly for the finished message
* where the key is from derive_finished() and the seed is the transcript
* hash).
*
* @param key key to use with the PRF
* @param seed seed to use with the PRF
* @param out output from the PRF (allocated)
* @return TRUE if output was generated
*/
bool (*allocate_bytes)(tls_hkdf_t *this, chunk_t key, chunk_t seed,
chunk_t *out);
/**
* Destroy a tls_hkdf_t
*/
void (*destroy)(tls_hkdf_t *this);
};
/**
* Create a tls_hkdf instance.
*
* @param hash_algorithm hash algorithm to use
* @param psk Pre shared key if available otherwise NULL
* @return TLS HKDF helper
*/
tls_hkdf_t *tls_hkdf_create(hash_algorithm_t hash_algorithm, chunk_t psk);
#endif /** TLS_HKDF_H_ @}*/