/*
* Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdlib.h>
#include "ssl_local.h"
#include "internal/ktls.h"
#include "record/record_local.h"
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include <openssl/core_names.h>
#define TLS13_MAX_LABEL_LEN 249
#ifdef CHARSET_EBCDIC
static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 };
#else
static const unsigned char label_prefix[] = "tls13 ";
#endif
/*
* Given a |secret|; a |label| of length |labellen|; and |data| of length
* |datalen| (e.g. typically a hash of the handshake messages), derive a new
* secret |outlen| bytes long and store it in the location pointed to be |out|.
* The |data| value may be zero length. Any errors will be treated as fatal if
* |fatal| is set. Returns 1 on success 0 on failure.
*/
int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
const unsigned char *label, size_t labellen,
const unsigned char *data, size_t datalen,
unsigned char *out, size_t outlen, int fatal)
{
EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF,
s->ctx->propq);
EVP_KDF_CTX *kctx;
OSSL_PARAM params[7], *p = params;
int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
const char *mdname = EVP_MD_get0_name(md);
int ret;
size_t hashlen;
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
if (kctx == NULL)
return 0;
if (labellen > TLS13_MAX_LABEL_LEN) {
if (fatal) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
} else {
/*
* Probably we have been called from SSL_export_keying_material(),
* or SSL_export_keying_material_early().
*/
ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
}
EVP_KDF_CTX_free(kctx);
return 0;
}
if ((ret = EVP_MD_get_size(md)) <= 0) {
EVP_KDF_CTX_free(kctx);
if (fatal)
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
else
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
hashlen = (size_t)ret;
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
(char *)mdname, 0);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
(unsigned char *)secret, hashlen);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
(unsigned char *)label_prefix,
sizeof(label_prefix) - 1);
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
(unsigned char *)label, labellen);
if (data != NULL)
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA,
(unsigned char *)data,
datalen);
*p++ = OSSL_PARAM_construct_end();
ret = EVP_KDF_derive(kctx, out, outlen, params) <= 0;
EVP_KDF_CTX_free(kctx);
if (ret != 0) {
if (fatal)
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
else
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
}
return ret == 0;
}
/*
* Given a |secret| generate a |key| of length |keylen| bytes. Returns 1 on
* success 0 on failure.
*/
int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret,
unsigned char *key, size_t keylen)
{
#ifdef CHARSET_EBCDIC
static const unsigned char keylabel[] ={ 0x6B, 0x65, 0x79, 0x00 };
#else
static const unsigned char keylabel[] = "key";
#endif
return tls13_hkdf_expand(s, md, secret, keylabel, sizeof(keylabel) - 1,
NULL, 0, key, keylen, 1);
}
/*
* Given a |secret| generate an |iv| of length |ivlen| bytes. Returns 1 on
* success 0 on failure.
*/
int tls13_derive_iv(SSL *s, const EVP_MD *md, const unsigned char *secret,
unsigned char *iv, size_t ivlen)
{
#ifdef CHARSET_EBCDIC
static const unsigned char ivlabel[] = { 0x69, 0x76, 0x00 };