+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+ if (s->msg_callback) {
+ s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
+ p, len, s, s->msg_callback_arg);
+ s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
+ s->s3->client_random, SSL3_RANDOM_SIZE,
+ s, s->msg_callback_arg);
+ s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
+ s->s3->server_random, SSL3_RANDOM_SIZE,
+ s, s->msg_callback_arg);
+ s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
+ s->session->master_key,
+ SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg);
+ }
+#endif
+
+#ifdef KSSL_DEBUG
+ fprintf(stderr, "tls1_generate_master_secret() complete\n");
+#endif /* KSSL_DEBUG */
+ return (SSL3_MASTER_SECRET_SIZE);
+}
+
+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+ const char *label, size_t llen,
+ const unsigned char *context,
+ size_t contextlen, int use_context)
+{
+ unsigned char *buff;
+ unsigned char *val = NULL;
+ size_t vallen, currentvalpos;
+ int rv;
+
+#ifdef KSSL_DEBUG
+ fprintf(stderr, "tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n",
+ s, out, olen, label, llen, context, contextlen);
+#endif /* KSSL_DEBUG */
+
+ buff = OPENSSL_malloc(olen);
+ if (buff == NULL)
+ goto err2;
+
+ /*
+ * construct PRF arguments we construct the PRF argument ourself rather
+ * than passing separate values into the TLS PRF to ensure that the
+ * concatenation of values does not create a prohibited label.
+ */
+ vallen = llen + SSL3_RANDOM_SIZE * 2;
+ if (use_context) {
+ vallen += 2 + contextlen;
+ }
+
+ val = OPENSSL_malloc(vallen);
+ if (val == NULL)
+ goto err2;
+ currentvalpos = 0;
+ memcpy(val + currentvalpos, (unsigned char *)label, llen);
+ currentvalpos += llen;
+ memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
+ currentvalpos += SSL3_RANDOM_SIZE;
+ memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
+ currentvalpos += SSL3_RANDOM_SIZE;
+
+ if (use_context) {
+ val[currentvalpos] = (contextlen >> 8) & 0xff;
+ currentvalpos++;
+ val[currentvalpos] = contextlen & 0xff;
+ currentvalpos++;
+ if ((contextlen > 0) || (context != NULL)) {
+ memcpy(val + currentvalpos, context, contextlen);
+ }
+ }
+
+ /*
+ * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
+ * label len) = 15, so size of val > max(prohibited label len) = 15 and
+ * the comparisons won't have buffer overflow
+ */
+ if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
+ TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0)
+ goto err1;
+ if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
+ TLS_MD_SERVER_FINISH_CONST_SIZE) == 0)
+ goto err1;
+ if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
+ TLS_MD_MASTER_SECRET_CONST_SIZE) == 0)
+ goto err1;
+ if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
+ TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0)
+ goto err1;
+
+ rv = tls1_PRF(ssl_get_algorithm2(s),
+ val, vallen,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ s->session->master_key, s->session->master_key_length,
+ out, buff, olen);
+