From 1fde71cf6954c04a0da0f35afafb7774643e13d2 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date: Tue, 16 May 2017 13:11:29 +0200
Subject: [PATCH 3/6] Added the TLS 1.2 PRF and test vectors

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
---
 testsuite/.test-rules.make |  3 +++
 testsuite/Makefile.in      |  2 +-
 testsuite/tls12-prf-test.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 tls1-prf.c                 | 44 +++++++++++++++++++++++++++++++++++++++++
 tls1-prf.h                 |  9 +++++++++
 5 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 testsuite/tls12-prf-test.c

diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make
index dbeb7a1..d09a68b 100644
--- a/testsuite/.test-rules.make
+++ b/testsuite/.test-rules.make
@@ -64,6 +64,9 @@ salsa20-test$(EXEEXT): salsa20-test.$(OBJEXT)
 tls10-prf-test$(EXEEXT): tls10-prf-test.$(OBJEXT)
 	$(LINK) tls10-prf-test.$(OBJEXT) $(TEST_OBJS) -o tls10-prf-test$(EXEEXT)
 
+tls12-prf-test$(EXEEXT): tls12-prf-test.$(OBJEXT)
+	$(LINK) tls12-prf-test.$(OBJEXT) $(TEST_OBJS) -o tls12-prf-test$(EXEEXT)
+
 sha1-test$(EXEEXT): sha1-test.$(OBJEXT)
 	$(LINK) sha1-test.$(OBJEXT) $(TEST_OBJS) -o sha1-test$(EXEEXT)
 
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 3deee1c..d8c312b 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -18,7 +18,7 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
 		    md2-test.c md4-test.c md5-test.c md5-compat-test.c \
 		    memeql-test.c memxor-test.c gosthash94-test.c \
 		    ripemd160-test.c \
-		    salsa20-test.c tls10-prf-test.c \
+		    salsa20-test.c tls10-prf-test.c tls12-prf-test.c \
 		    sha1-test.c sha224-test.c sha256-test.c \
 		    sha384-test.c sha512-test.c sha512-224-test.c sha512-256-test.c \
 		    sha3-permute-test.c sha3-224-test.c sha3-256-test.c \
diff --git a/testsuite/tls12-prf-test.c b/testsuite/tls12-prf-test.c
new file mode 100644
index 0000000..eae8421
--- /dev/null
+++ b/testsuite/tls12-prf-test.c
@@ -0,0 +1,49 @@
+#include "testutils.h"
+#include "tls1-prf.h"
+#include "hmac.h"
+
+static
+void test_tls12_sha256_prf(const struct tstring *secret, const struct tstring *seed,
+	const struct tstring *label, const struct tstring *output)
+{
+	struct hmac_sha256_ctx ctx;
+	uint8_t *buffer = xalloc(output->length);
+
+	hmac_sha256_set_key(&ctx, secret->length, secret->data);
+	tls12_prf(&ctx, (nettle_hash_update_func*)hmac_sha256_update,
+		  (nettle_hash_digest_func*)hmac_sha256_digest, SHA256_DIGEST_SIZE,
+		  label->length, (char*)label->data,
+		  seed->length, seed->data, output->length, buffer);
+
+	if (MEMEQ(output->length, output->data, buffer) == 0) {
+		fprintf(stdout, "\nGot:\n");
+		print_hex(output->length, buffer);
+		fprintf(stdout, "\nExpected:\n");
+		print_hex(output->length, output->data);
+		abort();
+	}
+	free(buffer);
+}
+
+void
+test_main(void)
+{
+  /* TLS 1.2 SHA256-PRF vectors generated by _gnutls_prf_raw() */
+  test_tls12_sha256_prf(SHEX("0450b0ea9ecd3602ee0d76c5c3c86f4a"),
+  	SHEX("207acc0254b867f5b925b45a33601d8b"),
+  	SDATA("test label"), SHEX("ae679e0e714f5975763768b166979e1d"));
+
+  test_tls12_sha256_prf(SHEX("34204a9df0be6eb4e925a8027cf6c602"),
+  	SHEX("98b2c40bcd664c83bb920c18201a6395"),
+  	SDATA("test label"), SHEX("afa9312453c22fa83d2b511b372d73a402a2a62873239a51fade45082faf3fd2bb7ffb3e9bf36e28b3141aaba484005332a9f9e388a4d329f1587a4b317da07708ea1ba95a53f8786724bd83ce4b03af"));
+
+  test_tls12_sha256_prf(SHEX("a3691aa1f6814b80592bf1cf2acf1697"),
+  	SHEX("5523d41e320e694d0c1ff5734d830b933e46927071c92621"),
+  	SDATA("test label"), SHEX("6ad0984fa06f78fe161bd46d7c261de43340d728dddc3d0ff0dd7e0d"));
+
+  test_tls12_sha256_prf(SHEX("210ec937069707e5465bc46bf779e104108b18fdb793be7b218dbf145c8641f3"), SHEX("1e351a0baf35c79945924394b881cfe31dae8f1c1ed54d3b"),
+  	SDATA("test label"), SHEX("7653fa809cde3b553c4a17e2cdbcc918f36527f22219a7d7f95d97243ff2d5dee8265ef0af03"));
+
+
+}
+
diff --git a/tls1-prf.c b/tls1-prf.c
index 3c5172e..f07395a 100644
--- a/tls1-prf.c
+++ b/tls1-prf.c
@@ -131,3 +131,47 @@ tls10_prf(size_t secret_size, const uint8_t *secret,
 
 	return;
 }
+
+/*-
+ * 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.
+ -*/
+void
+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)
+{
+	size_t cseed_size;
+
+	TMP_DECL(cseed, uint8_t, MAX_SEED_SIZE);
+
+	/* label+seed = cseed */
+	cseed_size = seed_size + label_size;
+
+	TMP_ALLOC (cseed, cseed_size);
+
+	memcpy(cseed, label, label_size);
+	memcpy(&cseed[label_size], seed, seed_size);
+
+	P_hash(mac_ctx, update, digest, digest_size,
+		cseed_size, cseed, length, dst);
+
+	return;
+}
diff --git a/tls1-prf.h b/tls1-prf.h
index fdcef1d..da2739e 100644
--- a/tls1-prf.h
+++ b/tls1-prf.h
@@ -42,6 +42,7 @@ extern "C" {
 
 /* Namespace mangling */
 #define tls10_prf nettle_tls10_prf
+#define tls12_prf nettle_tls12_prf
 
 void
 tls10_prf(size_t secret_size, const uint8_t *secret,
@@ -49,6 +50,14 @@ tls10_prf(size_t secret_size, const uint8_t *secret,
 	  size_t seed_size, const uint8_t *seed,
 	  size_t length, uint8_t *dst);
 
+void
+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);
 
 #ifdef __cplusplus
 }
-- 
2.9.3

