summaryrefslogtreecommitdiffstats
path: root/lib/nettle/int/tls1-prf.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:33:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:33:12 +0000
commit36082a2fe36ecd800d784ae44c14f1f18c66a7e9 (patch)
tree6c68e0c0097987aff85a01dabddd34b862309a7c /lib/nettle/int/tls1-prf.c
parentInitial commit. (diff)
downloadgnutls28-36082a2fe36ecd800d784ae44c14f1f18c66a7e9.tar.xz
gnutls28-36082a2fe36ecd800d784ae44c14f1f18c66a7e9.zip
Adding upstream version 3.7.9.upstream/3.7.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/nettle/int/tls1-prf.c')
-rw-r--r--lib/nettle/int/tls1-prf.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/nettle/int/tls1-prf.c b/lib/nettle/int/tls1-prf.c
new file mode 100644
index 0000000..19ca5d3
--- /dev/null
+++ b/lib/nettle/int/tls1-prf.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS 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/>
+ *
+ */
+
+/* Functions for the TLS PRF handling.
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gnutls_int.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <nettle/hmac.h>
+#include <nettle/memxor.h>
+#include "int/tls1-prf.h"
+#include <nettle/sha1.h>
+#include <nettle/md5.h>
+
+
+/* The RFC2246 P_hash() function. The mac_ctx is expected to
+ * be initialized and key set to be the secret key.
+ */
+static void
+P_hash( void *mac_ctx,
+ nettle_hash_update_func *update,
+ nettle_hash_digest_func *digest,
+ size_t digest_size,
+ size_t seed_size, const uint8_t *seed,
+ size_t label_size, const char *label,
+ size_t dst_length,
+ uint8_t *dst)
+{
+ uint8_t Atmp[MAX_HASH_SIZE];
+ ssize_t left;
+ unsigned started = 0;
+
+ /* round up */
+ left = dst_length;
+
+ while(left > 0) {
+ if (started == 0) { /* A(0) */
+ update(mac_ctx, label_size, (const uint8_t *)label); /* hash label */
+ update(mac_ctx, seed_size, seed);
+ started = 1;
+ } else {
+ update(mac_ctx, digest_size, Atmp);
+ }
+ digest(mac_ctx, digest_size, Atmp); /* store A(i) */
+
+ update(mac_ctx, digest_size, Atmp); /* hash A(i) */
+ update(mac_ctx, label_size, (const uint8_t *)label); /* hash label */
+ update(mac_ctx, seed_size, seed); /* hash seed */
+
+ if (left < (ssize_t)digest_size)
+ digest_size = left;
+
+ digest(mac_ctx, digest_size, dst);
+
+ left -= digest_size;
+ dst += digest_size;
+ }
+
+ return;
+}
+
+int
+tls10_prf(size_t secret_size, const uint8_t *secret,
+ size_t label_size, const char *label,
+ size_t seed_size, const uint8_t *seed,
+ size_t length, uint8_t *dst)
+{
+ int l_s;
+ const uint8_t *s1, *s2;
+ struct hmac_md5_ctx md5_ctx;
+ struct hmac_sha1_ctx sha1_ctx;
+ uint8_t o1[MAX_PRF_BYTES];
+
+ if (length > MAX_PRF_BYTES)
+ return 0;
+
+ l_s = secret_size / 2;
+ s1 = &secret[0];
+ s2 = &secret[l_s];
+ if (secret_size % 2 != 0) {
+ l_s++;
+ }
+
+ hmac_md5_set_key(&md5_ctx, l_s, s1);
+
+ P_hash(&md5_ctx, (nettle_hash_update_func*)hmac_md5_update,
+ (nettle_hash_digest_func*)hmac_md5_digest,
+ MD5_DIGEST_SIZE,
+ seed_size, seed, label_size, label, length, o1);
+
+ hmac_sha1_set_key(&sha1_ctx, l_s, s2);
+
+ P_hash(&sha1_ctx, (nettle_hash_update_func*)hmac_sha1_update,
+ (nettle_hash_digest_func*)hmac_sha1_digest,
+ SHA1_DIGEST_SIZE,
+ seed_size, seed, label_size, label, length, dst);
+
+ memxor(dst, o1, length);
+
+ return 1;
+}
+
+/*-
+ * tls12_prf:
+ * @mac_ctx: a MAC context initialized with key being the secret
+ * @update: a MAC update function
+ * @digest: a MAC digest function
+ * @digest_size: the MAC output size
+ * @label_size: the size of the label
+ * @label: the label to apply
+ * @seed_size: the seed size
+ * @seed: the seed
+ * @length: size of desired PRF output
+ * @dst: the location to store output
+ *
+ * The TLS 1.2 Pseudo-Random-Function (PRF).
+ *
+ * Returns: zero on failure, non zero on success.
+ -*/
+int
+tls12_prf(void *mac_ctx,
+ nettle_hash_update_func *update,
+ nettle_hash_digest_func *digest,
+ size_t digest_size,
+ size_t label_size, const char *label,
+ size_t seed_size, const uint8_t *seed,
+ size_t length, uint8_t *dst)
+{
+ P_hash(mac_ctx, update, digest, digest_size,
+ seed_size, seed, label_size, label, length, dst);
+
+ return 1;
+}