diff options
Diffstat (limited to 'lib/nettle/prf.c')
-rw-r--r-- | lib/nettle/prf.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/nettle/prf.c b/lib/nettle/prf.c new file mode 100644 index 0000000..631ba3b --- /dev/null +++ b/lib/nettle/prf.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2017 Red Hat, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/> + * + */ + +#include <gnutls_int.h> +#include "int/tls1-prf.h" +#include <nettle/hmac.h> +#if ENABLE_GOST +#include "gost/hmac-gost.h" +#endif + +/*- + * _gnutls_prf_raw: + * @mac: the MAC algorithm to use, set to %GNUTLS_MAC_MD5_SHA1 for the TLS1.0 mac + * @master_size: length of the @master variable. + * @master: the master secret used in PRF computation + * @label_size: length of the @label variable. + * @label: label used in PRF computation, typically a short string. + * @seed_size: length of the @seed variable. + * @seed: optional extra data to seed the PRF with. + * @outsize: size of pre-allocated output buffer to hold the output. + * @out: pre-allocated buffer to hold the generated data. + * + * Apply the TLS Pseudo-Random-Function (PRF) on the master secret + * and the provided data. + * + * Returns: %GNUTLS_E_SUCCESS on success, or an error code. + -*/ +int +_gnutls_prf_raw(gnutls_mac_algorithm_t mac, + size_t master_size, const void *master, + size_t label_size, const char *label, + size_t seed_size, const uint8_t *seed, size_t outsize, char *out) +{ + int ret; + + switch (mac) { + case GNUTLS_MAC_MD5_SHA1: + tls10_prf(master_size, (uint8_t*)master, label_size, label, + seed_size, seed, outsize, (uint8_t*)out); + return 0; + case GNUTLS_MAC_SHA256:{ + struct hmac_sha256_ctx ctx; + hmac_sha256_set_key(&ctx, master_size, (uint8_t*)master); + + ret = tls12_prf(&ctx, + (nettle_hash_update_func *) + hmac_sha256_update, + (nettle_hash_digest_func *) + hmac_sha256_digest, SHA256_DIGEST_SIZE, + label_size, label, seed_size, + seed, outsize, + (uint8_t*)out); + + if (unlikely(ret != 1)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + break; + } + case GNUTLS_MAC_SHA384:{ + struct hmac_sha384_ctx ctx; + hmac_sha384_set_key(&ctx, master_size, master); + + ret = tls12_prf(&ctx, + (nettle_hash_update_func *) + hmac_sha384_update, + (nettle_hash_digest_func *) + hmac_sha384_digest, SHA384_DIGEST_SIZE, + label_size, label, seed_size, + seed, outsize, + (uint8_t*)out); + + if (unlikely(ret != 1)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + break; + } +#if ENABLE_GOST + case GNUTLS_MAC_STREEBOG_256:{ + struct hmac_streebog256_ctx ctx; + hmac_streebog256_set_key(&ctx, master_size, master); + + ret = tls12_prf(&ctx, + (nettle_hash_update_func *) + hmac_streebog256_update, + (nettle_hash_digest_func *) + hmac_streebog256_digest, STREEBOG256_DIGEST_SIZE, + label_size, label, seed_size, + seed, outsize, + (uint8_t*)out); + + if (unlikely(ret != 1)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + break; + } + case GNUTLS_MAC_STREEBOG_512:{ + struct hmac_streebog512_ctx ctx; + hmac_streebog512_set_key(&ctx, master_size, master); + + ret = tls12_prf(&ctx, + (nettle_hash_update_func *) + hmac_streebog512_update, + (nettle_hash_digest_func *) + hmac_streebog512_digest, STREEBOG512_DIGEST_SIZE, + label_size, label, seed_size, + seed, outsize, + (uint8_t*)out); + + if (unlikely(ret != 1)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + break; + } +#endif + default: + gnutls_assert(); + _gnutls_debug_log("unhandled PRF %s\n", + gnutls_mac_get_name(mac)); + return GNUTLS_E_INVALID_REQUEST; + + } + + return 0; +} |