summaryrefslogtreecommitdiff
path: root/lib/nettle/int
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-05-31 13:52:03 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-06-01 08:52:58 +0200
commita46b5cb535a2ccb7a6ffa7672399182e094923c5 (patch)
treefdc9680f5ef54c061985f1285f02e6d51d2005c1 /lib/nettle/int
parent18f42d025c229ef5066245578f45c1771e1b6ec7 (diff)
downloadgnutls-a46b5cb535a2ccb7a6ffa7672399182e094923c5.tar.gz
prf: implement the TLS 1.0 and 1.2 PRFs using nettle
That simplifies the existing PRF code and moves it in the crypto-backend component. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/nettle/int')
-rw-r--r--lib/nettle/int/tls1-prf.c169
-rw-r--r--lib/nettle/int/tls1-prf.h50
2 files changed, 219 insertions, 0 deletions
diff --git a/lib/nettle/int/tls1-prf.c b/lib/nettle/int/tls1-prf.c
new file mode 100644
index 0000000000..94228c6d7c
--- /dev/null
+++ b/lib/nettle/int/tls1-prf.c
@@ -0,0 +1,169 @@
+/*
+ * 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 <http://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 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, 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, 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, cseed_size = seed_size + label_size;
+ const uint8_t *s1, *s2;
+ struct hmac_md5_ctx md5_ctx;
+ struct hmac_sha1_ctx sha1_ctx;
+ uint8_t o1[MAX_PRF_BYTES];
+ uint8_t cseed[MAX_SEED_SIZE];
+
+ if (cseed_size > MAX_SEED_SIZE || length > MAX_PRF_BYTES)
+ return 0;
+
+ memcpy(cseed, label, label_size);
+ memcpy(&cseed[label_size], seed, seed_size);
+
+ 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,
+ cseed_size, cseed, 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,
+ cseed_size, cseed, 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)
+{
+ size_t cseed_size = seed_size + label_size;
+ uint8_t cseed[MAX_SEED_SIZE];
+
+ if (cseed_size > MAX_SEED_SIZE)
+ return 0;
+
+ 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 1;
+}
diff --git a/lib/nettle/int/tls1-prf.h b/lib/nettle/int/tls1-prf.h
new file mode 100644
index 0000000000..a455377571
--- /dev/null
+++ b/lib/nettle/int/tls1-prf.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef TLS_PRF_H_INCLUDED
+#define TLS_PRF_H_INCLUDED
+
+#include <nettle/nettle-meta.h>
+
+#define MAX_SEED_SIZE 200
+#define MAX_PRF_BYTES 200
+
+/* Namespace mangling */
+#define tls10_prf nettle_tls10_prf
+#define tls12_prf nettle_tls12_prf
+
+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
+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);
+
+#endif /* TLS_PRF_H_INCLUDED */